Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
daf9ce0
Add trigger binding support (Jul 15)
JatinSanghvi Jul 27, 2022
6e33204
Add trigger binding support
JatinSanghvi Jul 27, 2022
443692f
Handle all supported characters in table and column names
JatinSanghvi Jul 28, 2022
2a14a73
Address review comments on Readme file
JatinSanghvi Jul 28, 2022
b011dea
Address review comments on SqlTriggerListener
JatinSanghvi Jul 29, 2022
0497251
Address review comments on SqlTableChangeMonitor
JatinSanghvi Jul 29, 2022
24886a1
Fix code comment
JatinSanghvi Jul 29, 2022
db8fdc9
Add telemetry events for trigger binding (#289)
JatinSanghvi Aug 9, 2022
ca410db
Throw exception for unsupported column types (#291)
JatinSanghvi Aug 10, 2022
5b295c4
Merge branch 'main' into triggerbindings
JatinSanghvi Aug 17, 2022
d2ffb21
Enable PR validation for triggerbindings branch (#298)
JatinSanghvi Aug 18, 2022
5dc95f2
Renew all leases through single statement (#297)
JatinSanghvi Aug 20, 2022
f07e265
Merge branch 'main' into triggerbindings
Charles-Gagnon Aug 22, 2022
f1b2739
Add new integration tests for trigger binding (#296)
JatinSanghvi Aug 25, 2022
2bf4388
Do not open extra SQL connections (#318)
JatinSanghvi Aug 25, 2022
7833025
Use constants for worker table column names (#310)
JatinSanghvi Aug 25, 2022
d467956
Rename worker table to leases table (#319)
JatinSanghvi Aug 26, 2022
d5f2036
Fix spelling (#322)
Charles-Gagnon Aug 29, 2022
3330551
Fix duplicate key error when exceptions occur (#323)
Charles-Gagnon Aug 30, 2022
42be679
Merge branch 'main' into triggerbindings
Charles-Gagnon Aug 30, 2022
d544da9
Fix trigger tutorial location
Charles-Gagnon Aug 30, 2022
0d3a057
Fix README
Charles-Gagnon Aug 30, 2022
74901da
Add more debug logging (#324)
Charles-Gagnon Aug 30, 2022
f912d2c
Do not process rows if lease acquisition fails (#339)
JatinSanghvi Sep 9, 2022
a27b080
Wait for error inside `StartFunctionsHostAndWaitForError` method (#349)
JatinSanghvi Sep 14, 2022
f23083b
Add test for multiple triggered functions (#343)
JatinSanghvi Sep 14, 2022
f42d273
Add retry when attempting to release leases (#340)
AmeyaRele Sep 14, 2022
1dad068
Refactor locking logic in class `SqlTableChangeMonitor` (#357)
JatinSanghvi Sep 16, 2022
f4185a1
Merge commit '365efceb0fcb5dcb5f01957e6fd870070f628a0f' into triggerb…
Charles-Gagnon Sep 19, 2022
930f190
cherry-pick c5a746f7e70de3ed050289d3ab2651a39667abda
Charles-Gagnon Sep 2, 2022
3410e23
Merge commit '76575f29e964f3487684b84e279444279296f5c2' into chgagnon…
Charles-Gagnon Sep 19, 2022
4df33f9
Merge pull request #359 from Azure/chgagnon/mergeFromMain1
Charles-Gagnon Sep 19, 2022
d36422f
Add comments to explain LastSyncVersion selection (#358)
AmeyaRele Sep 20, 2022
942736c
Fix
Charles-Gagnon Sep 20, 2022
89f7981
Move test scripts
Charles-Gagnon Sep 20, 2022
a42b0fb
Merge branch 'main' into chgagnon/mergeFromMain3
Charles-Gagnon Sep 20, 2022
8270663
Merge pull request #360 from Azure/chgagnon/mergeFromMain2
Charles-Gagnon Sep 20, 2022
a7f19af
Merge pull request #361 from Azure/chgagnon/mergeFromMain3
Charles-Gagnon Sep 20, 2022
56d8289
Constructor cleanup (#362)
Charles-Gagnon Sep 20, 2022
2717881
Add configuration for batch size/polling interval (#364)
Charles-Gagnon Sep 22, 2022
e82dfe3
Refactor how trigger integration tests wait for changes (#368)
Charles-Gagnon Sep 26, 2022
f840a27
Always disable telemetry during integration tests (#372)
Charles-Gagnon Sep 27, 2022
5d8a8b6
Check for reserved column names on all columns (#369)
Charles-Gagnon Sep 27, 2022
cec3504
Generate timeout during each test (#371)
Charles-Gagnon Sep 27, 2022
3aced07
Increase default trigger throughput and add benchmark tests (#374)
Charles-Gagnon Sep 27, 2022
8c01883
Add TriggerMonitorStart event (#376)
Charles-Gagnon Sep 27, 2022
2b043b8
Add test for multiple function hosts (#344)
JatinSanghvi Oct 5, 2022
ed8b268
Add comment for explaining token cancellation (#387)
AmeyaRele Oct 10, 2022
72751fe
Update README and code comments (#391)
Charles-Gagnon Oct 12, 2022
0b6e647
Merge branch 'main' into triggerbindings
Charles-Gagnon Oct 13, 2022
b966b42
Merge pull request #398 from Azure/chgagnon/mergeFromMain
Charles-Gagnon Oct 13, 2022
3a4ddd3
Fix polling size override using wrong configuration value
Charles-Gagnon Oct 14, 2022
2e0f345
Fixes
Charles-Gagnon Oct 14, 2022
360587c
Update comments
Charles-Gagnon Oct 14, 2022
42d301e
typo
Charles-Gagnon Oct 14, 2022
450180e
more changes
Charles-Gagnon Oct 14, 2022
a150c9f
Merge pull request #401 from Azure/chgagnon/fixPollingSize
Charles-Gagnon Oct 14, 2022
513e3ff
Use merge query for renewing leases
Charles-Gagnon Oct 17, 2022
1dc0512
Add runtime driven scaling support (#389)
JatinSanghvi Oct 18, 2022
eecf69c
Remove logging
Charles-Gagnon Oct 18, 2022
940602c
simplify
Charles-Gagnon Oct 18, 2022
8bb73ec
Merge branch 'triggerbindings' into chgagnon/mergeRenewLeases
Charles-Gagnon Oct 18, 2022
02a3c5f
fix compile
Charles-Gagnon Oct 18, 2022
1671e08
Add const
Charles-Gagnon Oct 18, 2022
767285b
Merge pull request #405 from Azure/chgagnon/mergeRenewLeases
Charles-Gagnon Oct 20, 2022
5cd760a
Add unit tests for runtime driven scaling (#414)
JatinSanghvi Oct 22, 2022
55639aa
Merge branch 'main' into triggerbindings
Charles-Gagnon Oct 28, 2022
e46dc42
Use lower Functions SDK package
Charles-Gagnon Oct 28, 2022
02d5da7
undo unintended changes
Charles-Gagnon Oct 28, 2022
e6ba062
Merge branch 'main' into chgagnon/triggerMDS5
Charles-Gagnon Nov 1, 2022
55903a3
Add trigger scaling configuration (#428)
AmeyaRele Nov 2, 2022
59762fe
Merge pull request #429 from Azure/chgagnon/triggerMDS5
Charles-Gagnon Nov 2, 2022
be7c63b
Perf test fixes
Charles-Gagnon Nov 2, 2022
181a77e
truncate
Charles-Gagnon Nov 2, 2022
69d9634
e2 -> ex
Charles-Gagnon Nov 2, 2022
2af6fc5
Merge pull request #439 from Azure/chgagnon/perfFixes
Charles-Gagnon Nov 2, 2022
6a7ba22
More perf testing fixes/improvements
Charles-Gagnon Nov 2, 2022
238ce83
Add operation
Charles-Gagnon Nov 2, 2022
9c41537
Merge pull request #445 from Azure/chgagnon/batchInsert
Charles-Gagnon Nov 3, 2022
2bd0bed
Static import SqlTriggerConstants
Charles-Gagnon Nov 3, 2022
fcc3249
Merge pull request #451 from Azure/chgagnon/usingStatic
Charles-Gagnon Nov 3, 2022
43480cd
initial
Charles-Gagnon Nov 4, 2022
7367c92
updates
Charles-Gagnon Nov 4, 2022
7d4fd75
Use app locks for all transactions
Charles-Gagnon Nov 4, 2022
14fa061
Add resource comment
Charles-Gagnon Nov 4, 2022
aa9bdf5
Merge pull request #453 from Azure/chgagnon/morePerfTrigger
Charles-Gagnon Nov 7, 2022
6469902
comma
Charles-Gagnon Nov 7, 2022
4f8ef9c
Merge pull request #455 from Azure/chgagnon/appLock
Charles-Gagnon Nov 7, 2022
0078e6d
Throw exception for scaling configuration invalid value (#450)
AmeyaRele Nov 7, 2022
f48e331
Catch SqlException for existing object error (#456)
AmeyaRele Nov 7, 2022
ae8fe39
Fix perf tests
Charles-Gagnon Nov 7, 2022
3e41737
more
Charles-Gagnon Nov 7, 2022
500f74c
Merge pull request #460 from Azure/chgagnon/fixPerfTests
Charles-Gagnon Nov 8, 2022
bcd00dd
Add more app lock statements (#463)
Charles-Gagnon Nov 8, 2022
7458755
Validate monitor config values and send max changes configuration on …
Charles-Gagnon Nov 8, 2022
607bd4d
Move magic numbers to constants (#465)
Charles-Gagnon Nov 8, 2022
9e2cd97
Update triggerbinding packages to align with main (#468)
Charles-Gagnon Nov 8, 2022
e813a4b
Remove triggerbindings from pr builds
Charles-Gagnon Nov 8, 2022
b51a4b0
Merge branch 'main' into chgagnon/triggerbindingsmerge
Charles-Gagnon Nov 8, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ dotnet_analyzer_diagnostic.severity = error
# Namespace does not match folder structure - Ideally this should be enabled but it seems to have issues with root level files so disabling for now
dotnet_diagnostic.IDE0130.severity = none

# CA1805: Do not initialize unnecessarily - It's better to be explicit when initializing vars to ensure correct value is used
dotnet_diagnostic.CA1805.severity = none

# Documentation related errors, remove once they are fixed
dotnet_diagnostic.CS1591.severity = none
dotnet_diagnostic.CS1573.severity = none
Expand Down
198 changes: 180 additions & 18 deletions README.md

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions performance/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# See https://github.com/dotnet/roslyn-analyzers/blob/main/.editorconfig for an example on different settings and how they're used

[*.cs]

# Disabled
dotnet_diagnostic.CA1309.severity = silent # Use ordinal StringComparison - this isn't important for tests and just adds clutter
dotnet_diagnostic.CA1305.severity = silent # Specify IFormatProvider - this isn't important for tests and just adds clutter
dotnet_diagnostic.CA1707.severity = silent # Identifiers should not contain underscores - this helps make test names more readable
dotnet_diagnostic.CA2201.severity = silent # Do not raise reserved exception types - tests can throw whatever they want
dotnet_diagnostic.CA1051.severity = silent # Do not declare visible instance fields - doesn't matter for tests
5 changes: 5 additions & 0 deletions performance/SqlBindingBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ public static void Main()
{
BenchmarkRunner.Run<SqlInputBindingPerformance>();
BenchmarkRunner.Run<SqlOutputBindingPerformance>();
BenchmarkRunner.Run<SqlTriggerBindingPerformance>();
BenchmarkRunner.Run<SqlTriggerBindingPerformance_BatchOverride>();
BenchmarkRunner.Run<SqlTriggerBindingPerformance_PollingIntervalOverride>();
BenchmarkRunner.Run<SqlTriggerPerformance_Overrides>();
BenchmarkRunner.Run<SqlTriggerBindingPerformance_Parallelization>();
}
}
}
38 changes: 38 additions & 0 deletions performance/SqlTriggerBindingPerformance.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.Sql.Samples.TriggerBindingSamples;
using Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common;
using BenchmarkDotNet.Attributes;

namespace Microsoft.Azure.WebJobs.Extensions.Sql.Performance
{
[MemoryDiagnoser]
public class SqlTriggerBindingPerformance : SqlTriggerBindingPerformanceTestBase
{
[GlobalSetup]
public void GlobalSetup()
{
this.SetChangeTrackingForTable("Products", true);
this.StartFunctionHost(nameof(ProductsTrigger), SupportedLanguages.CSharp);
}

[Benchmark]
[Arguments(1)]
[Arguments(10)]
[Arguments(100)]
[Arguments(1000)]
public async Task ProductsTriggerTest(int count)
{
await this.WaitForProductChanges(
1,
count,
SqlChangeOperation.Insert,
() => { this.InsertProducts(1, count); return Task.CompletedTask; },
id => $"Product {id}",
id => id * 100,
this.GetBatchProcessingTimeout(1, count));
}
}
}
40 changes: 40 additions & 0 deletions performance/SqlTriggerBindingPerformanceTestBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Integration;
using BenchmarkDotNet.Attributes;

namespace Microsoft.Azure.WebJobs.Extensions.Sql.Performance
{
public class SqlTriggerBindingPerformanceTestBase : SqlTriggerBindingIntegrationTests
{
[IterationCleanup]
public void IterationCleanup()
{
// Delete all rows in Products table after each iteration so we start fresh each time
this.ExecuteNonQuery("TRUNCATE TABLE Products");
// Clear the leases table, otherwise we may end up getting blocked by leases from a previous run
this.ExecuteNonQuery(@"DECLARE @cmd varchar(100)
DECLARE cmds CURSOR FOR
SELECT 'TRUNCATE TABLE az_func.' + Name + ''
FROM sys.tables
WHERE Name LIKE 'Leases_%'

OPEN cmds
WHILE 1 = 1
BEGIN
FETCH cmds INTO @cmd
IF @@fetch_status != 0 BREAK
EXEC(@cmd)
END
CLOSE cmds;
DEALLOCATE cmds");
}

[GlobalCleanup]
public void GlobalCleanup()
{
this.Dispose();
}
}
}
67 changes: 67 additions & 0 deletions performance/SqlTriggerBindingPerformance_Parallelization.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.Sql.Samples.TriggerBindingSamples;
using Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common;
using BenchmarkDotNet.Attributes;

namespace Microsoft.Azure.WebJobs.Extensions.Sql.Performance
{
[MemoryDiagnoser]
public class SqlTriggerBindingPerformance_Parallelization : SqlTriggerBindingPerformanceTestBase
{
[Params(2, 5)]
public int HostCount;

[GlobalSetup]
public void GlobalSetup()
{
this.SetChangeTrackingForTable("Products", true);
for (int i = 0; i < this.HostCount; ++i)
{
this.StartFunctionHost(nameof(ProductsTrigger), SupportedLanguages.CSharp);
}
}

[Benchmark]
public async Task MultiHost()
{
int firstId = 1;
int lastId = 90;
await this.WaitForProductChanges(
firstId,
lastId,
SqlChangeOperation.Insert,
() => { this.InsertProducts(firstId, lastId); return Task.CompletedTask; },
id => $"Product {id}",
id => id * 100,
this.GetBatchProcessingTimeout(firstId, lastId));

firstId = 1;
lastId = 60;
// All table columns (not just the columns that were updated) would be returned for update operation.
await this.WaitForProductChanges(
firstId,
lastId,
SqlChangeOperation.Update,
() => { this.UpdateProducts(firstId, lastId); return Task.CompletedTask; },
id => $"Updated Product {id}",
id => id * 100,
this.GetBatchProcessingTimeout(firstId, lastId));

firstId = 31;
lastId = 90;
// The properties corresponding to non-primary key columns would be set to the C# type's default values
// (null and 0) for delete operation.
await this.WaitForProductChanges(
firstId,
lastId,
SqlChangeOperation.Delete,
() => { this.DeleteProducts(firstId, lastId); return Task.CompletedTask; },
_ => null,
_ => 0,
this.GetBatchProcessingTimeout(firstId, lastId));
}
}
}
49 changes: 49 additions & 0 deletions performance/SqlTriggerPerformance_BatchOverride.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.Sql.Samples.TriggerBindingSamples;
using Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common;
using BenchmarkDotNet.Attributes;
using System.Collections.Generic;

namespace Microsoft.Azure.WebJobs.Extensions.Sql.Performance
{
[MemoryDiagnoser]
public class SqlTriggerBindingPerformance_BatchOverride : SqlTriggerBindingPerformanceTestBase
{

[Params(100, 1000)]
public int BatchSize;

[GlobalSetup]
public void GlobalSetup()
{
this.SetChangeTrackingForTable("Products", true);
this.StartFunctionHost(
nameof(ProductsTrigger),
SupportedLanguages.CSharp,
environmentVariables: new Dictionary<string, string>() {
{ "Sql_Trigger_BatchSize", this.BatchSize.ToString() }
});
}

[Benchmark]
[Arguments(0.1)]
[Arguments(0.5)]
[Arguments(1)]
[Arguments(5)]
public async Task Run(double numBatches)
{
int count = (int)(numBatches * this.BatchSize);
await this.WaitForProductChanges(
1,
count,
SqlChangeOperation.Insert,
() => { this.InsertProducts(1, count); return Task.CompletedTask; },
id => $"Product {id}",
id => id * 100,
this.GetBatchProcessingTimeout(1, count, batchSize: this.BatchSize));
}
}
}
53 changes: 53 additions & 0 deletions performance/SqlTriggerPerformance_Overrides.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.Sql.Samples.TriggerBindingSamples;
using Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common;
using BenchmarkDotNet.Attributes;
using System.Collections.Generic;

namespace Microsoft.Azure.WebJobs.Extensions.Sql.Performance
{
[MemoryDiagnoser]
public class SqlTriggerPerformance_Overrides : SqlTriggerBindingPerformanceTestBase
{
[Params(1, 10, 100, 500)]
public int PollingIntervalMs;

[Params(500, 1000, 2000)]
public int BatchSize;

[GlobalSetup]
public void GlobalSetup()
{
this.SetChangeTrackingForTable("Products", true);
this.StartFunctionHost(
nameof(ProductsTrigger),
SupportedLanguages.CSharp,
environmentVariables: new Dictionary<string, string>() {
{ "Sql_Trigger_BatchSize", this.BatchSize.ToString() },
{ "Sql_Trigger_PollingIntervalMs", this.PollingIntervalMs.ToString() }
});
}

[Benchmark]
[Arguments(0.1)]
[Arguments(0.5)]
[Arguments(1)]
[Arguments(5)]
[Arguments(10)]
public async Task Run(double numBatches)
{
int count = (int)(numBatches * this.BatchSize);
await this.WaitForProductChanges(
1,
count,
SqlChangeOperation.Insert,
() => { this.InsertProducts(1, count); return Task.CompletedTask; },
id => $"Product {id}",
id => id * 100,
this.GetBatchProcessingTimeout(1, count, batchSize: this.BatchSize));
}
}
}
44 changes: 44 additions & 0 deletions performance/SqlTriggerPerformance_PollingIntervalOverride.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.Sql.Samples.TriggerBindingSamples;
using Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common;
using BenchmarkDotNet.Attributes;
using System.Collections.Generic;

namespace Microsoft.Azure.WebJobs.Extensions.Sql.Performance
{
[MemoryDiagnoser]
public class SqlTriggerBindingPerformance_PollingIntervalOverride : SqlTriggerBindingPerformanceTestBase
{
[Params(1, 10, 100, 500, 2000)]
public int PollingIntervalMs;

[GlobalSetup]
public void GlobalSetup()
{
this.SetChangeTrackingForTable("Products", true);
this.StartFunctionHost(
nameof(ProductsTrigger),
SupportedLanguages.CSharp,
environmentVariables: new Dictionary<string, string>() {
{ "Sql_Trigger_PollingIntervalMs", this.PollingIntervalMs.ToString() }
});
}

[Benchmark]
public async Task Run()
{
int count = SqlTableChangeMonitor<object>.DefaultBatchSize * 2;
await this.WaitForProductChanges(
1,
count,
SqlChangeOperation.Insert,
() => { this.InsertProducts(1, count); return Task.CompletedTask; },
id => $"Product {id}",
id => id * 100,
this.GetBatchProcessingTimeout(1, count, pollingIntervalMs: this.PollingIntervalMs));
}
}
}
23 changes: 23 additions & 0 deletions samples/samples-csharp/TriggerBindingSamples/ProductsTrigger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Collections.Generic;
using Microsoft.Azure.WebJobs.Extensions.Sql.Samples.Common;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace Microsoft.Azure.WebJobs.Extensions.Sql.Samples.TriggerBindingSamples
{
public static class ProductsTrigger
{
[FunctionName(nameof(ProductsTrigger))]
public static void Run(
[SqlTrigger("[dbo].[Products]", ConnectionStringSetting = "SqlConnectionString")]
IReadOnlyList<SqlChange<Product>> changes,
ILogger logger)
{
// The output is used to inspect the trigger binding parameter in test methods.
logger.LogInformation("SQL Changes: " + JsonConvert.SerializeObject(changes));
}
}
}
1 change: 1 addition & 0 deletions src/Microsoft.Azure.WebJobs.Extensions.Sql.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
<PackageReference Include="Microsoft.AspNetCore.Http" />
<InternalsVisibleTo Include="Microsoft.Azure.WebJobs.Extensions.Sql.Tests" Key="0024000004800000940000000602000000240000525341310004000001000100272736ad6e5f9586bac2d531eabc3acc666c2f8ec879fa94f8f7b0327d2ff2ed523448f83c3d5c5dd2dfc7bc99c5286b2c125117bf5cbe242b9d41750732b2bdffe649c6efb8e5526d526fdd130095ecdb7bf210809c6cdad8824faa9ac0310ac3cba2aa0523567b2dfa7fe250b30facbd62d4ec99b94ac47c7d3b28f1f6e4c8" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" Key="0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7" />
<InternalsVisibleTo Include="Microsoft.Azure.WebJobs.Extensions.Sql.Performance" Key="0024000004800000940000000602000000240000525341310004000001000100272736ad6e5f9586bac2d531eabc3acc666c2f8ec879fa94f8f7b0327d2ff2ed523448f83c3d5c5dd2dfc7bc99c5286b2c125117bf5cbe242b9d41750732b2bdffe649c6efb8e5526d526fdd130095ecdb7bf210809c6cdad8824faa9ac0310ac3cba2aa0523567b2dfa7fe250b30facbd62d4ec99b94ac47c7d3b28f1f6e4c8"/>
</ItemGroup>

<ItemGroup>
Expand Down
Loading