diff --git a/Samples/Dapper/ElasticDapper.csproj b/Samples/Dapper/ElasticDapper.csproj
index 8305c65..6eed8f5 100644
--- a/Samples/Dapper/ElasticDapper.csproj
+++ b/Samples/Dapper/ElasticDapper.csproj
@@ -5,14 +5,13 @@
-
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/Samples/Dapper/Program.cs b/Samples/Dapper/Program.cs
index dafc787..f60417c 100644
--- a/Samples/Dapper/Program.cs
+++ b/Samples/Dapper/Program.cs
@@ -3,7 +3,7 @@
using System;
using System.Collections.Generic;
-using System.Data.SqlClient;
+using Microsoft.Data.SqlClient;
using Dapper;
using DapperExtensions;
using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement;
@@ -67,89 +67,74 @@ public static void Main()
Console.Write("Enter a name for a new Blog: ");
var name = Console.ReadLine();
- SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
+ using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(
+ key: s_tenantId1,
+ connectionString: connStrBldr.ConnectionString,
+ options: ConnectionOptions.Validate))
{
- using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(
- key: s_tenantId1,
- connectionString: connStrBldr.ConnectionString,
- options: ConnectionOptions.Validate))
- {
- var blog = new Blog { Name = name };
- sqlconn.Insert(blog);
- }
- });
+ var blog = new Blog { Name = name };
+ sqlconn.Insert(blog);
+ }
- SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
+ using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(
+ key: s_tenantId1,
+ connectionString: connStrBldr.ConnectionString,
+ options: ConnectionOptions.Validate))
{
- using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(
- key: s_tenantId1,
- connectionString: connStrBldr.ConnectionString,
- options: ConnectionOptions.Validate))
+ // Display all Blogs for tenant 1
+ IEnumerable result = sqlconn.Query(@"
+ SELECT *
+ FROM Blog
+ ORDER BY Name");
+
+ Console.WriteLine("All blogs for tenant id {0}:", s_tenantId1);
+ foreach (var item in result)
{
- // Display all Blogs for tenant 1
- IEnumerable result = sqlconn.Query(@"
- SELECT *
- FROM Blog
- ORDER BY Name");
-
- Console.WriteLine("All blogs for tenant id {0}:", s_tenantId1);
- foreach (var item in result)
- {
- Console.WriteLine(item.Name);
- }
+ Console.WriteLine(item.Name);
}
- });
+ }
// Do work for tenant 2 :-)
// Here I am going to illustrate how to integrate
// with DapperExtensions which saves us the T-SQL
//
- SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
+ using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(
+ key: s_tenantId2,
+ connectionString: connStrBldr.ConnectionString,
+ options: ConnectionOptions.Validate))
{
- using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(
- key: s_tenantId2,
- connectionString: connStrBldr.ConnectionString,
- options: ConnectionOptions.Validate))
+ // Display all Blogs for tenant 2
+ IEnumerable result = sqlconn.GetList();
+ Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2);
+ foreach (var item in result)
{
- // Display all Blogs for tenant 2
- IEnumerable result = sqlconn.GetList();
- Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2);
- foreach (var item in result)
- {
- Console.WriteLine(item.Name);
- }
+ Console.WriteLine(item.Name);
}
- });
+ }
// Create and save a new Blog
Console.Write("Enter a name for a new Blog: ");
var name2 = Console.ReadLine();
- SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
+ using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(
+ key: s_tenantId2,
+ connectionString: connStrBldr.ConnectionString,
+ options: ConnectionOptions.Validate))
{
- using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(
- key: s_tenantId2,
- connectionString: connStrBldr.ConnectionString,
- options: ConnectionOptions.Validate))
- {
- var blog = new Blog { Name = name2 };
- sqlconn.Insert(blog);
- }
- });
+ var blog = new Blog { Name = name2 };
+ sqlconn.Insert(blog);
+ }
- SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
+ using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(s_tenantId2, connStrBldr.ConnectionString, ConnectionOptions.Validate))
{
- using (SqlConnection sqlconn = shardingLayer.ShardMap.OpenConnectionForKey(s_tenantId2, connStrBldr.ConnectionString, ConnectionOptions.Validate))
+ // Display all Blogs for tenant 2
+ IEnumerable result = sqlconn.GetList();
+ Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2);
+ foreach (var item in result)
{
- // Display all Blogs for tenant 2
- IEnumerable result = sqlconn.GetList();
- Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2);
- foreach (var item in result)
- {
- Console.WriteLine(item.Name);
- }
+ Console.WriteLine(item.Name);
}
- });
+ }
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
@@ -168,6 +153,7 @@ private static void CreateSchema(string shardName)
using (SqlConnection conn = new SqlConnection(connStrBldr.ToString()))
{
+ conn.RetryLogicProvider = SqlDatabaseUtils.SqlRetryProvider;
conn.Open();
conn.Execute(@"
IF (OBJECT_ID('[dbo].[Blog]', 'U') IS NULL)
diff --git a/Samples/Dapper/Sharding.cs b/Samples/Dapper/Sharding.cs
index a7625cf..f92b404 100644
--- a/Samples/Dapper/Sharding.cs
+++ b/Samples/Dapper/Sharding.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-using System.Data.SqlClient;
+using Microsoft.Data.SqlClient;
using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement;
namespace ElasticDapper
diff --git a/Samples/Dapper/SqlDatabaseUtils.cs b/Samples/Dapper/SqlDatabaseUtils.cs
index 66de772..e235ead 100644
--- a/Samples/Dapper/SqlDatabaseUtils.cs
+++ b/Samples/Dapper/SqlDatabaseUtils.cs
@@ -2,7 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
-using Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling;
+using Microsoft.Data.SqlClient;
namespace ElasticDapper
{
@@ -11,12 +11,22 @@ namespace ElasticDapper
///
internal static class SqlDatabaseUtils
{
+ ///
+ /// Create a retry logic provider
+ ///
+ public static SqlRetryLogicBaseProvider SqlRetryProvider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(SqlRetryPolicy);
+
///
/// Gets the retry policy to use for connections to SQL Server.
///
- public static RetryPolicy SqlRetryPolicy
+ private static SqlRetryLogicOption SqlRetryPolicy => new()
{
- get { return new RetryPolicy(10, TimeSpan.FromSeconds(5)); }
- }
+ // Tries 5 times before throwing an exception
+ NumberOfTries = 5,
+ // Preferred gap time to delay before retry
+ DeltaTime = TimeSpan.FromSeconds(1),
+ // Maximum gap time for each delay time before retry
+ MaxTimeInterval = TimeSpan.FromSeconds(20)
+ };
}
}
diff --git a/Samples/EFCodeFirst/ElasticScaleContext.cs b/Samples/EFCodeFirst/ElasticScaleContext.cs
index d42ab1e..9ce1039 100644
--- a/Samples/EFCodeFirst/ElasticScaleContext.cs
+++ b/Samples/EFCodeFirst/ElasticScaleContext.cs
@@ -3,7 +3,7 @@
using System.Data.Common;
using System.Data.Entity;
-using System.Data.SqlClient;
+using Microsoft.Data.SqlClient;
using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement;
namespace EFCodeFirstElasticScale
diff --git a/Samples/EFCodeFirst/ElasticScaleDbConfiguration.cs b/Samples/EFCodeFirst/ElasticScaleDbConfiguration.cs
index 3c6b3b8..364f009 100644
--- a/Samples/EFCodeFirst/ElasticScaleDbConfiguration.cs
+++ b/Samples/EFCodeFirst/ElasticScaleDbConfiguration.cs
@@ -17,7 +17,7 @@ public ElasticScaleDbConfiguration()
// the SqlAzureExecutionStrategy which would lead to wrong retry behavior
// since it would not use the OpenConnectionForKey call.
// For more details, see http://msdn.microsoft.com/en-us/data/dn456835.aspx.
- this.SetExecutionStrategy("System.Data.SqlClient", () => new DefaultExecutionStrategy());
+ this.SetExecutionStrategy("Microsoft.Data.SqlClient", () => new DefaultExecutionStrategy());
// There are legitimate cases, typically for migrations during development
// using Add-Migration and Update-Datase, where a connection to a
diff --git a/Samples/EFCodeFirst/EntityFrameworkCodeFirst.csproj b/Samples/EFCodeFirst/EntityFrameworkCodeFirst.csproj
index bd76408..203c518 100644
--- a/Samples/EFCodeFirst/EntityFrameworkCodeFirst.csproj
+++ b/Samples/EFCodeFirst/EntityFrameworkCodeFirst.csproj
@@ -5,10 +5,6 @@
-
-
-
-
@@ -17,4 +13,7 @@
+
+
+
\ No newline at end of file
diff --git a/Samples/EFCodeFirst/Program.cs b/Samples/EFCodeFirst/Program.cs
index cec4e9e..3dc2721 100644
--- a/Samples/EFCodeFirst/Program.cs
+++ b/Samples/EFCodeFirst/Program.cs
@@ -2,7 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
-using System.Data.SqlClient;
+using Microsoft.Data.SqlClient;
using System.Linq;
////////////////////////////////////////////////////////////////////////////////////////
@@ -58,81 +58,66 @@ public static void Main()
Console.Write("Enter a name for a new Blog: ");
var name = Console.ReadLine();
- SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
+ using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId1, connStrBldr.ConnectionString))
{
- using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId1, connStrBldr.ConnectionString))
- {
- var blog = new Blog { Name = name };
- db.Blogs.Add(blog);
- db.SaveChanges();
- }
- });
+ var blog = new Blog { Name = name };
+ db.Blogs.Add(blog);
+ db.SaveChanges();
+ }
- SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
+ using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId1, connStrBldr.ConnectionString))
{
- using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId1, connStrBldr.ConnectionString))
+ // Display all Blogs for tenant 1
+ var query = from b in db.Blogs
+ orderby b.Name
+ select b;
+
+ Console.WriteLine("All blogs for tenant id {0}:", s_tenantId1);
+ foreach (var item in query)
{
- // Display all Blogs for tenant 1
- var query = from b in db.Blogs
- orderby b.Name
- select b;
-
- Console.WriteLine("All blogs for tenant id {0}:", s_tenantId1);
- foreach (var item in query)
- {
- Console.WriteLine(item.Name);
- }
+ Console.WriteLine(item.Name);
}
- });
+ }
// Do work for tenant 2 :-)
- SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
+ using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId2, connStrBldr.ConnectionString))
{
- using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId2, connStrBldr.ConnectionString))
+ // Display all Blogs from the database
+ var query = from b in db.Blogs
+ orderby b.Name
+ select b;
+
+ Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2);
+ foreach (var item in query)
{
- // Display all Blogs from the database
- var query = from b in db.Blogs
- orderby b.Name
- select b;
-
- Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2);
- foreach (var item in query)
- {
- Console.WriteLine(item.Name);
- }
+ Console.WriteLine(item.Name);
}
- });
+ }
// Create and save a new Blog
Console.Write("Enter a name for a new Blog: ");
var name2 = Console.ReadLine();
- SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
+ using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId2, connStrBldr.ConnectionString))
{
- using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId2, connStrBldr.ConnectionString))
- {
- var blog = new Blog { Name = name2 };
- db.Blogs.Add(blog);
- db.SaveChanges();
- }
- });
+ var blog = new Blog { Name = name2 };
+ db.Blogs.Add(blog);
+ db.SaveChanges();
+ }
- SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
+ using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId2, connStrBldr.ConnectionString))
{
- using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId2, connStrBldr.ConnectionString))
+ // Display all Blogs from the database
+ var query = from b in db.Blogs
+ orderby b.Name
+ select b;
+
+ Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2);
+ foreach (var item in query)
{
- // Display all Blogs from the database
- var query = from b in db.Blogs
- orderby b.Name
- select b;
-
- Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2);
- foreach (var item in query)
- {
- Console.WriteLine(item.Name);
- }
+ Console.WriteLine(item.Name);
}
- });
+ }
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
diff --git a/Samples/EFCodeFirst/Sharding.cs b/Samples/EFCodeFirst/Sharding.cs
index 8ad1457..e9ead47 100644
--- a/Samples/EFCodeFirst/Sharding.cs
+++ b/Samples/EFCodeFirst/Sharding.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-using System.Data.SqlClient;
+using Microsoft.Data.SqlClient;
using System.Linq;
using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement;
diff --git a/Samples/EFCodeFirst/SqlDatabaseUtils.cs b/Samples/EFCodeFirst/SqlDatabaseUtils.cs
index 2e63840..96830f4 100644
--- a/Samples/EFCodeFirst/SqlDatabaseUtils.cs
+++ b/Samples/EFCodeFirst/SqlDatabaseUtils.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
+using Microsoft.Data.SqlClient;
using Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling;
namespace EFCodeFirstElasticScale
@@ -11,12 +12,23 @@ namespace EFCodeFirstElasticScale
///
internal static class SqlDatabaseUtils
{
+ ///
+ /// Create a retry logic provider
+ ///
+ public static SqlRetryLogicBaseProvider SqlRetryProvider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(SqlRetryPolicy);
+
///
/// Gets the retry policy to use for connections to SQL Server.
///
- public static RetryPolicy SqlRetryPolicy
+ private static SqlRetryLogicOption SqlRetryPolicy => new()
{
- get { return new RetryPolicy(10, TimeSpan.FromSeconds(5)); }
- }
+ // Tries 5 times before throwing an exception
+ NumberOfTries = 5,
+ // Preferred gap time to delay before retry
+ DeltaTime = TimeSpan.FromSeconds(1),
+ // Maximum gap time for each delay time before retry
+ MaxTimeInterval = TimeSpan.FromSeconds(20)
+ };
+
}
}
diff --git a/Samples/EFMultiTenant/ElasticScaleContext.cs b/Samples/EFMultiTenant/ElasticScaleContext.cs
index b9d8ef6..99ac2c8 100644
--- a/Samples/EFMultiTenant/ElasticScaleContext.cs
+++ b/Samples/EFMultiTenant/ElasticScaleContext.cs
@@ -3,7 +3,7 @@
using System;
using System.Data.Entity;
-using System.Data.SqlClient;
+using Microsoft.Data.SqlClient;
using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement;
namespace EFMultiTenantElasticScale
diff --git a/Samples/EFMultiTenant/ElasticScaleDbConfiguration.cs b/Samples/EFMultiTenant/ElasticScaleDbConfiguration.cs
index 6945bac..aea6369 100644
--- a/Samples/EFMultiTenant/ElasticScaleDbConfiguration.cs
+++ b/Samples/EFMultiTenant/ElasticScaleDbConfiguration.cs
@@ -17,7 +17,7 @@ public ElasticScaleDbConfiguration()
// the SqlAzureExecutionStrategy which would lead to wrong retry behavior
// since it would not use the OpenConnectionForKey call.
// For more details, see http://msdn.microsoft.com/en-us/data/dn456835.aspx.
- this.SetExecutionStrategy("System.Data.SqlClient", () => new DefaultExecutionStrategy());
+ this.SetExecutionStrategy("Microsoft.Data.SqlClient", () => new DefaultExecutionStrategy());
// There are legitimate cases, typically for migrations during development
// using Add-Migration and Update-Datase, where a connection to a
diff --git a/Samples/EFMultiTenant/EntityFrameworkMultiTenant.csproj b/Samples/EFMultiTenant/EntityFrameworkMultiTenant.csproj
index 7a49864..51a43c3 100644
--- a/Samples/EFMultiTenant/EntityFrameworkMultiTenant.csproj
+++ b/Samples/EFMultiTenant/EntityFrameworkMultiTenant.csproj
@@ -5,10 +5,6 @@
-
-
-
-
@@ -20,4 +16,7 @@
+
+
+
diff --git a/Samples/EFMultiTenant/Program.cs b/Samples/EFMultiTenant/Program.cs
index 143f546..7832e74 100644
--- a/Samples/EFMultiTenant/Program.cs
+++ b/Samples/EFMultiTenant/Program.cs
@@ -3,7 +3,7 @@
using System;
using System.Data.Entity.Infrastructure;
-using System.Data.SqlClient;
+using Microsoft.Data.SqlClient;
using System.Linq;
////////////////////////////////////////////////////////////////////////////////////////
@@ -69,69 +69,62 @@ public static void Main()
Console.Write("\nEnter a name for a new Blog for TenantId {0}: ", tenantId);
var name = Console.ReadLine();
- SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
+ using (var db = new ElasticScaleContext(sharding.ShardMap, tenantId, connStrBldr.ConnectionString))
{
- using (var db = new ElasticScaleContext(sharding.ShardMap, tenantId, connStrBldr.ConnectionString))
+ var blog = new Blog { Name = name, TenantId = tenantId }; // must specify TenantId unless using default constraints to auto-populate
+ db.Blogs.Add(blog);
+ db.SaveChanges();
+
+ // If Row-Level Security is enabled, tenants will only display their own blogs
+ // Otherwise, tenants will see blogs for all tenants on the shard db
+ var query = from b in db.Blogs
+ orderby b.Name
+ select b;
+
+ Console.WriteLine("All blogs for TenantId {0}:", tenantId);
+ foreach (var item in query)
{
- var blog = new Blog { Name = name, TenantId = tenantId }; // must specify TenantId unless using default constraints to auto-populate
- db.Blogs.Add(blog);
- db.SaveChanges();
-
- // If Row-Level Security is enabled, tenants will only display their own blogs
- // Otherwise, tenants will see blogs for all tenants on the shard db
- var query = from b in db.Blogs
- orderby b.Name
- select b;
-
- Console.WriteLine("All blogs for TenantId {0}:", tenantId);
- foreach (var item in query)
- {
- Console.WriteLine(item.Name);
- }
+ Console.WriteLine(item.Name);
}
- });
+ }
}
// Example query via ADO.NET SqlClient
// If Row-Level Security is enabled, only Tenant 4's blogs will be listed
- SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
+ // Note: We are using a wrapper function OpenDDRConnection that automatically set SESSION_CONTEXT with the specified TenantId.
+ // This is a best practice to ensure that SESSION_CONTEXT is always set before executing a query.
+ using (SqlConnection conn = ElasticScaleContext.OpenDDRConnection(sharding.ShardMap, s_tenantId4, connStrBldr.ConnectionString))
{
- // Note: We are using a wrapper function OpenDDRConnection that automatically set SESSION_CONTEXT with the specified TenantId.
- // This is a best practice to ensure that SESSION_CONTEXT is always set before executing a query.
- using (SqlConnection conn = ElasticScaleContext.OpenDDRConnection(sharding.ShardMap, s_tenantId4, connStrBldr.ConnectionString))
- {
- SqlCommand cmd = conn.CreateCommand();
- cmd.CommandText = @"SELECT * FROM Blogs";
+ SqlCommand cmd = conn.CreateCommand();
+ cmd.RetryLogicProvider = SqlDatabaseUtils.SqlRetryProvider;
+ cmd.CommandText = @"SELECT * FROM Blogs";
- Console.WriteLine("\n--\n\nAll blogs for TenantId {0} (using ADO.NET SqlClient):", s_tenantId4);
- SqlDataReader reader = cmd.ExecuteReader();
- while (reader.Read())
- {
- Console.WriteLine("{0}", reader["Name"]);
- }
+ Console.WriteLine("\n--\n\nAll blogs for TenantId {0} (using ADO.NET SqlClient):", s_tenantId4);
+ SqlDataReader reader = cmd.ExecuteReader();
+ while (reader.Read())
+ {
+ Console.WriteLine("{0}", reader["Name"]);
}
- });
-
+ }
+
// Because of the RLS block predicate, attempting to insert a row for the wrong tenant will throw an error.
Console.WriteLine("\n--\n\nTrying to create a new Blog for TenantId {0} while connected as TenantId {1}: ", s_tenantId2, s_tenantId3);
- SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
+
+ using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId3, connStrBldr.ConnectionString))
{
- using (var db = new ElasticScaleContext(sharding.ShardMap, s_tenantId3, connStrBldr.ConnectionString))
+ // Verify that block predicate prevents Tenant 3 from inserting rows for Tenant 2
+ try
{
- // Verify that block predicate prevents Tenant 3 from inserting rows for Tenant 2
- try
- {
- var bad_blog = new Blog { Name = "BAD BLOG", TenantId = s_tenantId2 };
- db.Blogs.Add(bad_blog);
- db.SaveChanges();
- Console.WriteLine("No error thrown - make sure your security policy has a block predicate on this table in each shard database.");
- }
- catch (DbUpdateException)
- {
- Console.WriteLine("Can't insert blog for incorrect tenant.");
- }
+ var bad_blog = new Blog { Name = "BAD BLOG", TenantId = s_tenantId2 };
+ db.Blogs.Add(bad_blog);
+ db.SaveChanges();
+ Console.WriteLine("No error thrown - make sure your security policy has a block predicate on this table in each shard database.");
}
- });
+ catch (DbUpdateException)
+ {
+ Console.WriteLine("Can't insert blog for incorrect tenant.");
+ }
+ }
Console.WriteLine("\n--\n\nPress any key to exit...");
Console.ReadKey();
diff --git a/Samples/EFMultiTenant/Sharding.cs b/Samples/EFMultiTenant/Sharding.cs
index 2a601dd..7668456 100644
--- a/Samples/EFMultiTenant/Sharding.cs
+++ b/Samples/EFMultiTenant/Sharding.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-using System.Data.SqlClient;
+using Microsoft.Data.SqlClient;
using System.Linq;
using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement;
diff --git a/Samples/EFMultiTenant/SqlDatabaseUtils.cs b/Samples/EFMultiTenant/SqlDatabaseUtils.cs
index 7a10b1b..03d777a 100644
--- a/Samples/EFMultiTenant/SqlDatabaseUtils.cs
+++ b/Samples/EFMultiTenant/SqlDatabaseUtils.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
+using Microsoft.Data.SqlClient;
using Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling;
namespace EFMultiTenantElasticScale
@@ -11,12 +12,23 @@ namespace EFMultiTenantElasticScale
///
internal static class SqlDatabaseUtils
{
+ ///
+ /// Create a retry logic provider
+ ///
+ public static SqlRetryLogicBaseProvider SqlRetryProvider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(SqlRetryPolicy);
+
///
/// Gets the retry policy to use for connections to SQL Server.
///
- public static RetryPolicy SqlRetryPolicy
+ private static SqlRetryLogicOption SqlRetryPolicy => new()
{
- get { return new RetryPolicy(10, TimeSpan.FromSeconds(5)); }
- }
+ // Tries 5 times before throwing an exception
+ NumberOfTries = 5,
+ // Preferred gap time to delay before retry
+ DeltaTime = TimeSpan.FromSeconds(1),
+ // Maximum gap time for each delay time before retry
+ MaxTimeInterval = TimeSpan.FromSeconds(20)
+ };
+
}
}
diff --git a/Samples/ElasticScaleStarterKit/Configuration.cs b/Samples/ElasticScaleStarterKit/Configuration.cs
index 3d1fd33..c6f7578 100644
--- a/Samples/ElasticScaleStarterKit/Configuration.cs
+++ b/Samples/ElasticScaleStarterKit/Configuration.cs
@@ -2,7 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Configuration;
-using System.Data.SqlClient;
+using Microsoft.Data.SqlClient;
namespace ElasticScaleStarterKit
{
@@ -81,13 +81,15 @@ public static string GetCredentialsConnectionString()
string integratedSecurityString = ConfigurationManager.AppSettings["IntegratedSecurity"];
bool integratedSecurity = integratedSecurityString != null && bool.Parse(integratedSecurityString);
+ var entraSecurityString = ConfigurationManager.AppSettings["EntraSecurity"];
+ var entraSecurity = entraSecurityString != null && bool.Parse(entraSecurityString);
+
SqlConnectionStringBuilder connStr = new SqlConnectionStringBuilder
- {
- // DDR and MSQ require credentials to be set
- UserID = userId,
- Password = password,
+ {
IntegratedSecurity = integratedSecurity,
+ Authentication = entraSecurity ? SqlAuthenticationMethod.ActiveDirectoryInteractive : SqlAuthenticationMethod.NotSpecified,
+
// DataSource and InitialCatalog cannot be set for DDR and MSQ APIs, because these APIs will
// determine the DataSource and InitialCatalog for you.
//
@@ -100,6 +102,14 @@ public static string GetCredentialsConnectionString()
ApplicationName = "ESC_SKv1.0",
ConnectTimeout = 30
};
+
+ if (!integratedSecurity && !entraSecurity)
+ {
+ // DDR and MSQ require credentials to be set
+ connStr.UserID = userId;
+ connStr.Password = password;
+ }
+
return connStr.ToString();
}
}
diff --git a/Samples/ElasticScaleStarterKit/DataDependentRoutingSample.cs b/Samples/ElasticScaleStarterKit/DataDependentRoutingSample.cs
index 780b0f7..05bb1dc 100644
--- a/Samples/ElasticScaleStarterKit/DataDependentRoutingSample.cs
+++ b/Samples/ElasticScaleStarterKit/DataDependentRoutingSample.cs
@@ -2,7 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
-using System.Data.SqlClient;
+using Microsoft.Data.SqlClient;
using System.Linq;
using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement;
@@ -64,30 +64,30 @@ private static void AddCustomer(
// Open and execute the command with retry for transient faults. Note that if the command fails, the connection is closed, so
// the entire block is wrapped in a retry. This means that only one command should be executed per block, since if we had multiple
// commands then the first command may be executed multiple times if later commands fail.
- SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
+
+ // Looks up the key in the shard map and opens a connection to the shard
+ using (SqlConnection conn = shardMap.OpenConnectionForKey(customerId, credentialsConnectionString))
{
- // Looks up the key in the shard map and opens a connection to the shard
- using (SqlConnection conn = shardMap.OpenConnectionForKey(customerId, credentialsConnectionString))
- {
- // Create a simple command that will insert or update the customer information
- SqlCommand cmd = conn.CreateCommand();
- cmd.CommandText = @"
- IF EXISTS (SELECT 1 FROM Customers WHERE CustomerId = @customerId)
- UPDATE Customers
- SET Name = @name, RegionId = @regionId
- WHERE CustomerId = @customerId
- ELSE
- INSERT INTO Customers (CustomerId, Name, RegionId)
- VALUES (@customerId, @name, @regionId)";
- cmd.Parameters.AddWithValue("@customerId", customerId);
- cmd.Parameters.AddWithValue("@name", name);
- cmd.Parameters.AddWithValue("@regionId", regionId);
- cmd.CommandTimeout = 60;
-
- // Execute the command
- cmd.ExecuteNonQuery();
- }
- });
+ // Create a simple command that will insert or update the customer information
+ SqlCommand cmd = conn.CreateCommand();
+ cmd.RetryLogicProvider = SqlDatabaseUtils.SqlRetryProvider;
+
+ cmd.CommandText = @"
+ IF EXISTS (SELECT 1 FROM Customers WHERE CustomerId = @customerId)
+ UPDATE Customers
+ SET Name = @name, RegionId = @regionId
+ WHERE CustomerId = @customerId
+ ELSE
+ INSERT INTO Customers (CustomerId, Name, RegionId)
+ VALUES (@customerId, @name, @regionId)";
+ cmd.Parameters.AddWithValue("@customerId", customerId);
+ cmd.Parameters.AddWithValue("@name", name);
+ cmd.Parameters.AddWithValue("@regionId", regionId);
+ cmd.CommandTimeout = 60;
+
+ // Execute the command
+ cmd.ExecuteNonQuery();
+ }
}
///
@@ -99,26 +99,24 @@ private static void AddOrder(
int customerId,
int productId)
{
- SqlDatabaseUtils.SqlRetryPolicy.ExecuteAction(() =>
+ // Looks up the key in the shard map and opens a connection to the shard
+ using (SqlConnection conn = shardMap.OpenConnectionForKey(customerId, credentialsConnectionString))
{
- // Looks up the key in the shard map and opens a connection to the shard
- using (SqlConnection conn = shardMap.OpenConnectionForKey(customerId, credentialsConnectionString))
- {
- // Create a simple command that will insert a new order
- SqlCommand cmd = conn.CreateCommand();
-
- // Create a simple command
- cmd.CommandText = @"INSERT INTO dbo.Orders (CustomerId, OrderDate, ProductId)
- VALUES (@customerId, @orderDate, @productId)";
- cmd.Parameters.AddWithValue("@customerId", customerId);
- cmd.Parameters.AddWithValue("@orderDate", DateTime.Now.Date);
- cmd.Parameters.AddWithValue("@productId", productId);
- cmd.CommandTimeout = 60;
-
- // Execute the command
- cmd.ExecuteNonQuery();
- }
- });
+ // Create a simple command that will insert a new order
+ SqlCommand cmd = conn.CreateCommand();
+ cmd.RetryLogicProvider = SqlDatabaseUtils.SqlRetryProvider;
+
+ // Create a simple command
+ cmd.CommandText = @"INSERT INTO dbo.Orders (CustomerId, OrderDate, ProductId)
+ VALUES (@customerId, @orderDate, @productId)";
+ cmd.Parameters.AddWithValue("@customerId", customerId);
+ cmd.Parameters.AddWithValue("@orderDate", DateTime.Now.Date);
+ cmd.Parameters.AddWithValue("@productId", productId);
+ cmd.CommandTimeout = 60;
+
+ // Execute the command
+ cmd.ExecuteNonQuery();
+ }
ConsoleUtils.WriteInfo("Inserted order for customer ID: {0}", customerId);
}
diff --git a/Samples/ElasticScaleStarterKit/ElasticScaleStarterKit.csproj b/Samples/ElasticScaleStarterKit/ElasticScaleStarterKit.csproj
index a523329..9abd73f 100644
--- a/Samples/ElasticScaleStarterKit/ElasticScaleStarterKit.csproj
+++ b/Samples/ElasticScaleStarterKit/ElasticScaleStarterKit.csproj
@@ -5,10 +5,8 @@
-
-
-
-
+
+
@@ -20,4 +18,7 @@
+
+
+
\ No newline at end of file
diff --git a/Samples/ElasticScaleStarterKit/SqlDatabaseUtils.cs b/Samples/ElasticScaleStarterKit/SqlDatabaseUtils.cs
index 6049668..ef7313f 100644
--- a/Samples/ElasticScaleStarterKit/SqlDatabaseUtils.cs
+++ b/Samples/ElasticScaleStarterKit/SqlDatabaseUtils.cs
@@ -4,7 +4,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
-using System.Data.SqlClient;
+using Microsoft.Data.SqlClient;
using System.IO;
using System.Text;
using System.Threading;
@@ -34,11 +34,10 @@ public static bool TryConnectToSqlDatabase()
try
{
- using (ReliableSqlConnection conn = new ReliableSqlConnection(
- connectionString,
- SqlRetryPolicy,
- SqlRetryPolicy))
+ using (SqlConnection conn = new SqlConnection(
+ connectionString))
{
+ conn.RetryLogicProvider = SqlRetryProvider;
conn.Open();
}
@@ -55,18 +54,20 @@ public static bool TryConnectToSqlDatabase()
public static bool DatabaseExists(string server, string db)
{
- using (ReliableSqlConnection conn = new ReliableSqlConnection(
- Configuration.GetConnectionString(server, MasterDatabaseName),
- SqlRetryPolicy,
- SqlRetryPolicy))
+ using (SqlConnection conn = new SqlConnection(
+ Configuration.GetConnectionString(server, MasterDatabaseName)))
{
+ conn.RetryLogicProvider = SqlRetryProvider;
conn.Open();
SqlCommand cmd = conn.CreateCommand();
+ cmd.RetryLogicProvider = SqlRetryProvider;
+
cmd.CommandText = "select count(*) from sys.databases where name = @dbname";
cmd.Parameters.AddWithValue("@dbname", db);
cmd.CommandTimeout = 60;
- int count = conn.ExecuteCommand(cmd);
+
+ int count = (int)cmd.ExecuteScalar();
bool exists = count > 0;
return exists;
@@ -75,18 +76,20 @@ public static bool DatabaseExists(string server, string db)
public static bool DatabaseIsOnline(string server, string db)
{
- using (ReliableSqlConnection conn = new ReliableSqlConnection(
- Configuration.GetConnectionString(server, MasterDatabaseName),
- SqlRetryPolicy,
- SqlRetryPolicy))
+ using (SqlConnection conn = new SqlConnection(
+ Configuration.GetConnectionString(server, MasterDatabaseName)))
{
+ conn.RetryLogicProvider = SqlRetryProvider;
conn.Open();
SqlCommand cmd = conn.CreateCommand();
+ cmd.RetryLogicProvider = SqlRetryProvider;
+
cmd.CommandText = "select count(*) from sys.databases where name = @dbname and state = 0"; // online
cmd.Parameters.AddWithValue("@dbname", db);
cmd.CommandTimeout = 60;
- int count = conn.ExecuteCommand(cmd);
+
+ int count = (int)cmd.ExecuteScalar();
bool exists = count > 0;
return exists;
@@ -96,35 +99,33 @@ public static bool DatabaseIsOnline(string server, string db)
public static void CreateDatabase(string server, string db)
{
ConsoleUtils.WriteInfo("Creating database {0}", db);
- using (ReliableSqlConnection conn = new ReliableSqlConnection(
- Configuration.GetConnectionString(server, MasterDatabaseName),
- SqlRetryPolicy,
- SqlRetryPolicy))
+ using (SqlConnection conn = new SqlConnection(
+ Configuration.GetConnectionString(server, MasterDatabaseName)))
{
+ conn.RetryLogicProvider = SqlRetryProvider;
conn.Open();
SqlCommand cmd = conn.CreateCommand();
// Determine if we are connecting to Azure SQL DB
cmd.CommandText = "SELECT SERVERPROPERTY('EngineEdition')";
cmd.CommandTimeout = 60;
- int engineEdition = conn.ExecuteCommand(cmd);
+ cmd.RetryLogicProvider = SqlRetryProvider;
+
+ int engineEdition = (int)cmd.ExecuteScalar();
if (engineEdition == 5)
{
// Azure SQL DB
- SqlRetryPolicy.ExecuteAction(() =>
- {
- if (!DatabaseExists(server, db))
- {
- // Begin creation (which is async for Standard/Premium editions)
- cmd.CommandText = string.Format(
- "CREATE DATABASE {0} (EDITION = '{1}')",
- BracketEscapeName(db),
- Configuration.DatabaseEdition);
- cmd.CommandTimeout = 60;
- cmd.ExecuteNonQuery();
- }
- });
+ if (!DatabaseExists(server, db))
+ {
+ // Begin creation (which is async for Standard/Premium editions)
+ cmd.CommandText = string.Format(
+ "CREATE DATABASE {0} (EDITION = '{1}')",
+ BracketEscapeName(db),
+ Configuration.DatabaseEdition);
+ cmd.CommandTimeout = 180;
+ cmd.ExecuteNonQuery();
+ }
// Wait for the operation to complete
while (!DatabaseIsOnline(server, db))
@@ -139,7 +140,7 @@ public static void CreateDatabase(string server, string db)
{
// Other edition of SQL DB
cmd.CommandText = string.Format("CREATE DATABASE {0}", BracketEscapeName(db));
- conn.ExecuteCommand(cmd);
+ cmd.ExecuteNonQuery();
}
}
}
@@ -147,18 +148,17 @@ public static void CreateDatabase(string server, string db)
public static void DropDatabase(string server, string db)
{
ConsoleUtils.WriteInfo("Dropping database {0}", db);
- using (ReliableSqlConnection conn = new ReliableSqlConnection(
- Configuration.GetConnectionString(server, MasterDatabaseName),
- SqlRetryPolicy,
- SqlRetryPolicy))
+ using (SqlConnection conn = new SqlConnection(
+ Configuration.GetConnectionString(server, MasterDatabaseName)))
{
+ conn.RetryLogicProvider = SqlRetryProvider;
conn.Open();
SqlCommand cmd = conn.CreateCommand();
// Determine if we are connecting to Azure SQL DB
cmd.CommandText = "SELECT SERVERPROPERTY('EngineEdition')";
cmd.CommandTimeout = 60;
- int engineEdition = conn.ExecuteCommand(cmd);
+ int engineEdition = (int)cmd.ExecuteScalar();
// Drop the database
if (engineEdition == 5)
@@ -182,13 +182,13 @@ public static void DropDatabase(string server, string db)
public static void ExecuteSqlScript(string server, string db, string schemaFile)
{
ConsoleUtils.WriteInfo("Executing script {0}", schemaFile);
- using (ReliableSqlConnection conn = new ReliableSqlConnection(
- Configuration.GetConnectionString(server, db),
- SqlRetryPolicy,
- SqlRetryPolicy))
+ using (SqlConnection conn = new SqlConnection(
+ Configuration.GetConnectionString(server, db)))
{
+ conn.RetryLogicProvider = SqlRetryProvider;
conn.Open();
SqlCommand cmd = conn.CreateCommand();
+ cmd.RetryLogicProvider = SqlRetryProvider;
// Read the commands from the sql script file
IEnumerable commands = ReadSqlScript(schemaFile);
@@ -197,7 +197,7 @@ public static void ExecuteSqlScript(string server, string db, string schemaFile)
{
cmd.CommandText = command;
cmd.CommandTimeout = 60;
- conn.ExecuteCommand(cmd);
+ cmd.ExecuteNonQuery();
}
}
}
@@ -234,68 +234,20 @@ private static string BracketEscapeName(string sqlName)
return '[' + sqlName.Replace("]", "]]") + ']';
}
- ///
- /// Gets the retry policy to use for connections to SQL Server.
- ///
- public static RetryPolicy SqlRetryPolicy
- {
- get
- {
- return new RetryPolicy(10, TimeSpan.FromSeconds(5));
- }
- }
+ // Create a retry logic provider
+ public static SqlRetryLogicBaseProvider SqlRetryProvider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(SqlRetryPolicy);
///
- /// Extended sql transient error detection strategy that performs additional transient error
- /// checks besides the ones done by the enterprise library.
+ /// Gets the retry policy to use for connections to SQL Server.
///
- private class ExtendedSqlDatabaseTransientErrorDetectionStrategy : ITransientErrorDetectionStrategy
+ private static SqlRetryLogicOption SqlRetryPolicy => new()
{
- ///
- /// Enterprise transient error detection strategy.
- ///
- private SqlDatabaseTransientErrorDetectionStrategy _sqltransientErrorDetectionStrategy = new SqlDatabaseTransientErrorDetectionStrategy();
-
- ///
- /// Checks with enterprise library's default handler to see if the error is transient, additionally checks
- /// for such errors using the code in the in function.
- ///
- /// Exception being checked.
- /// true if exception is considered transient, false otherwise.
- public bool IsTransient(Exception ex)
- {
- return _sqltransientErrorDetectionStrategy.IsTransient(ex) || IsTransientException(ex);
- }
-
- ///
- /// Detects transient errors not currently considered as transient by the enterprise library's strategy.
- ///
- /// Input exception.
- /// true if exception is considered transient, false otherwise.
- private static bool IsTransientException(Exception ex)
- {
- SqlException se = ex as SqlException;
-
- if (se != null && se.InnerException != null)
- {
- Win32Exception we = se.InnerException as Win32Exception;
-
- if (we != null)
- {
- switch (we.NativeErrorCode)
- {
- case 0x102:
- // Transient wait expired error resulting in timeout
- return true;
- case 0x121:
- // Transient semaphore wait expired error resulting in timeout
- return true;
- }
- }
- }
-
- return false;
- }
- }
+ // Tries 5 times before throwing an exception
+ NumberOfTries = 5,
+ // Preferred gap time to delay before retry
+ DeltaTime = TimeSpan.FromSeconds(1),
+ // Maximum gap time for each delay time before retry
+ MaxTimeInterval = TimeSpan.FromSeconds(20)
+ };
}
}
diff --git a/Samples/ShardSqlCmd/Program.cs b/Samples/ShardSqlCmd/Program.cs
index 5ce8a42..53b7ad2 100644
--- a/Samples/ShardSqlCmd/Program.cs
+++ b/Samples/ShardSqlCmd/Program.cs
@@ -5,7 +5,7 @@
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
-using System.Data.SqlClient;
+using Microsoft.Data.SqlClient;
using System.Diagnostics;
using System.Linq;
using System.Text;
diff --git a/Samples/ShardSqlCmd/ShardSqlCmd.csproj b/Samples/ShardSqlCmd/ShardSqlCmd.csproj
index 432852a..5f83b3b 100644
--- a/Samples/ShardSqlCmd/ShardSqlCmd.csproj
+++ b/Samples/ShardSqlCmd/ShardSqlCmd.csproj
@@ -6,9 +6,9 @@
-
+
-
+
diff --git a/Src/ElasticScale.Client/Microsoft.Azure.SqlDatabase.ElasticScale.Client.csproj b/Src/ElasticScale.Client/Microsoft.Azure.SqlDatabase.ElasticScale.Client.csproj
index ac4c846..26ce352 100644
--- a/Src/ElasticScale.Client/Microsoft.Azure.SqlDatabase.ElasticScale.Client.csproj
+++ b/Src/ElasticScale.Client/Microsoft.Azure.SqlDatabase.ElasticScale.Client.csproj
@@ -9,7 +9,7 @@
Microsoft
net6.0
Microsoft;Elastic;Scale;Azure;SQL;DB;Database;Shard;Sharding;Management;Query;azureofficial
- Updated to net6.0 and migrated from System.Data.SqlClient to Microsoft.Data.SqlClient.
+ Updated to net6.0 and migrated from Microsoft.Data.SqlClient to Microsoft.Data.SqlClient.
Icon.png
https://github.com/Azure/elastic-db-tools
MIT
@@ -24,7 +24,7 @@
-
+
@@ -51,11 +51,4 @@
PerformanceCounters.Designer.cs
-
-
-
- 2.1.2
-
-
-
diff --git a/Test/ElasticScale.ClientTestCommon/Microsoft.Azure.SqlDatabase.ElasticScale.ClientTestCommon.csproj b/Test/ElasticScale.ClientTestCommon/Microsoft.Azure.SqlDatabase.ElasticScale.ClientTestCommon.csproj
index cfb54d1..b1b401c 100644
--- a/Test/ElasticScale.ClientTestCommon/Microsoft.Azure.SqlDatabase.ElasticScale.ClientTestCommon.csproj
+++ b/Test/ElasticScale.ClientTestCommon/Microsoft.Azure.SqlDatabase.ElasticScale.ClientTestCommon.csproj
@@ -6,7 +6,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/Test/ElasticScale.Query.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests.csproj b/Test/ElasticScale.Query.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests.csproj
index 97b9f29..6ae32d3 100644
--- a/Test/ElasticScale.Query.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests.csproj
+++ b/Test/ElasticScale.Query.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests.csproj
@@ -7,10 +7,9 @@
-
-
-
-
+
+
+
diff --git a/Test/ElasticScale.Query.UnitTests/MultiShardTestUtils.cs b/Test/ElasticScale.Query.UnitTests/MultiShardTestUtils.cs
index e012536..e16cb1b 100644
--- a/Test/ElasticScale.Query.UnitTests/MultiShardTestUtils.cs
+++ b/Test/ElasticScale.Query.UnitTests/MultiShardTestUtils.cs
@@ -47,12 +47,12 @@ internal static class MultiShardTestUtils
///
/// Connection string for local shard user.
///
- internal static string ShardConnectionString = @"Integrated Security=SSPI;";
+ internal static string ShardConnectionString = @"Integrated Security=SSPI;TrustServerCertificate=True;";
///
/// Connection string for global shard map manager operations.
///
- internal static string ShardMapManagerConnectionString = @"Data Source=localhost;Initial Catalog=ShardMapManager;Integrated Security=SSPI;";
+ internal static string ShardMapManagerConnectionString = @"Data Source=localhost;Initial Catalog=ShardMapManager;Integrated Security=SSPI;TrustServerCertificate=True;";
///
/// Name of the database where the ShardMapManager persists its data.
@@ -214,6 +214,8 @@ private static string GetTestConnectionString(string database)
builder.DataSource = s_serverLocation;
builder.IntegratedSecurity = true;
builder.InitialCatalog = database;
+ builder.TrustServerCertificate = true;
+
return builder.ConnectionString;
}
diff --git a/Test/ElasticScale.ShardManagement.UnitTests/Globals.cs b/Test/ElasticScale.ShardManagement.UnitTests/Globals.cs
index c706ca2..21035ab 100644
--- a/Test/ElasticScale.ShardManagement.UnitTests/Globals.cs
+++ b/Test/ElasticScale.ShardManagement.UnitTests/Globals.cs
@@ -22,22 +22,22 @@ internal static class Globals
///
/// Connection string for global shard map manager for Integrated Auth
///
- private const string ShardMapManagerConnString = ShardMapManagerConnStringBase + "Integrated Security=SSPI;";
+ private const string ShardMapManagerConnString = ShardMapManagerConnStringBase + "Integrated Security=SSPI;TrustServerCertificate=True;";
///
/// Connection string for global shard map manager for Sql Auth
///
- private const string ShardMapManagerConnStringForSqlAuth = ShardMapManagerConnStringBase + "Integrated Security=False;";
+ private const string ShardMapManagerConnStringForSqlAuth = ShardMapManagerConnStringBase + "Integrated Security=False;TrustServerCertificate=True;";
///
/// Connect string for local shard user.
///
- private const string ShardUserConnString = @"Integrated Security=SSPI;";
+ private const string ShardUserConnString = @"Integrated Security=SSPI;TrustServerCertificate=True;";
///
/// Connect string for local shard user.
///
- private const string ShardUserConnStringForSqlAuth = @"User={0};Password={1}";
+ private const string ShardUserConnStringForSqlAuth = @"User={0};Password={1};TrustServerCertificate=True;";
///
/// shardMapManager datasource name for unit tests.
@@ -57,7 +57,7 @@ internal static class Globals
///
/// Connection string for connecting to test server.
///
- internal const string ShardMapManagerTestConnectionString = @"Data Source=" + Globals.ShardMapManagerTestsDatasourceName + ";Integrated Security=SSPI;";
+ internal const string ShardMapManagerTestConnectionString = @"Data Source=" + Globals.ShardMapManagerTestsDatasourceName + ";Integrated Security=SSPI;TrustServerCertificate=True;";
///
/// Query to create database.
diff --git a/Test/ElasticScale.ShardManagement.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.UnitTests.csproj b/Test/ElasticScale.ShardManagement.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.UnitTests.csproj
index d755f90..dcde649 100644
--- a/Test/ElasticScale.ShardManagement.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.UnitTests.csproj
+++ b/Test/ElasticScale.ShardManagement.UnitTests/Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement.UnitTests.csproj
@@ -7,10 +7,9 @@
-
-
-
-
+
+
+
diff --git a/Test/ElasticScale.ShardManagement.UnitTests/ScenarioTests.cs b/Test/ElasticScale.ShardManagement.UnitTests/ScenarioTests.cs
index 26a1067..d24ebd1 100644
--- a/Test/ElasticScale.ShardManagement.UnitTests/ScenarioTests.cs
+++ b/Test/ElasticScale.ShardManagement.UnitTests/ScenarioTests.cs
@@ -308,14 +308,14 @@ public void BasicScenarioDefaultShardMaps()
{
// Also verify we can connect to the shard with Sql Auth, and Sql Auth using a secure credential
using (shardForConnection.OpenConnectionAsync(
- string.Empty,
+ "TrustServerCertificate=True;",
Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName),
ConnectionOptions.None).Result)
{
}
using (shardForConnection.OpenConnectionAsync(
- string.Empty,
+ "TrustServerCertificate=True;",
Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName)).Result)
{
}
@@ -1142,7 +1142,7 @@ public void BasicScenarioRangeShardMaps()
// Cover the OpenConnectionForKey overloads
using (SqlConnection conn = newMultiTenantShardMap.OpenConnectionForKey(
20,
- string.Empty,
+ "TrustServerCertificate=True;",
Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName)))
{
}
@@ -1237,7 +1237,7 @@ public void BasicScenarioRangeShardMaps()
// Cover the OpenConnectionForKeyAsync overloads
using (SqlConnection conn = multiTenantShardMap.OpenConnectionForKeyAsync(
20,
- string.Empty,
+ "TrustServerCertificate=True;",
Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName),
ConnectionOptions.None).Result)
{
@@ -1245,7 +1245,7 @@ public void BasicScenarioRangeShardMaps()
using (SqlConnection conn = multiTenantShardMap.OpenConnectionForKeyAsync(
20,
- string.Empty,
+ "TrustServerCertificate=True;",
Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName)).Result)
{
}
diff --git a/Test/ElasticScale.ShardManagement.UnitTests/ShardMapTests.cs b/Test/ElasticScale.ShardManagement.UnitTests/ShardMapTests.cs
index a1ee56a..a2bf280 100644
--- a/Test/ElasticScale.ShardManagement.UnitTests/ShardMapTests.cs
+++ b/Test/ElasticScale.ShardManagement.UnitTests/ShardMapTests.cs
@@ -221,12 +221,12 @@ public void CreateShardDefault()
}
// Validate that we can connect to the shard using a secure Sql Auth Credential
- using (sNew.OpenConnection(string.Empty, Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName)))
+ using (sNew.OpenConnection("TrustServerCertificate=True;", Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName)))
{
}
using (sNew.OpenConnection(
- string.Empty,
+ "TrustServerCertificate=True;",
Globals.ShardUserCredentialForSqlAuth(sqlAuthLogin.UniquifiedUserName),
ConnectionOptions.Validate))
{