Skip to content

Commit

Permalink
Merge pull request #249 from Azure/andreabatina/netstandard
Browse files Browse the repository at this point in the history
Updated Elastic Scale Client project to target .Net Standard 2.0 along with .net6.0 and updated sample apps to support AAD auth
  • Loading branch information
batinanet authored May 22, 2024
2 parents d6aeaf9 + f5bc10c commit 8838b77
Show file tree
Hide file tree
Showing 25 changed files with 1,268 additions and 1,157 deletions.
23 changes: 20 additions & 3 deletions ElasticDatabaseTools.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29709.97
# Visual Studio Version 17
VisualStudioVersion = 17.9.34728.123
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.SqlDatabase.ElasticScale.Client", "Src\ElasticScale.Client\Microsoft.Azure.SqlDatabase.ElasticScale.Client.csproj", "{4C3B3EC4-5702-469E-800E-313FB27A0A2B}"
EndProject
Expand All @@ -11,7 +11,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.SqlDatabase
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests", "Test\ElasticScale.Query.UnitTests\Microsoft.Azure.SqlDatabase.ElasticScale.Query.UnitTests.csproj", "{74CEE77F-D2C7-4B8B-9411-8F97F4E803FA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ElasticScaleStarterKit", "Samples\ElasticScaleStarterKit\ElasticScaleStarterKit.csproj", "{115A0283-AC42-4D37-97F2-106D168E04D2}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ElasticScaleStarterKit", "Samples\ElasticScaleStarterKit\ElasticScaleStarterKit.csproj", "{115A0283-AC42-4D37-97F2-106D168E04D2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFrameworkMultiTenant", "Samples\EFMultiTenant\EntityFrameworkMultiTenant.csproj", "{BC17F3EF-FEB4-4186-9342-E2D18F1E56AB}"
EndProject
Expand All @@ -21,6 +21,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ElasticDapper", "Samples\Da
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShardSqlCmd", "Samples\ShardSqlCmd\ShardSqlCmd.csproj", "{B210D6E5-7171-4117-9C77-3F2CB59D04D8}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{F7A2F005-3B53-495D-B0EC-CE41FAB4DC75}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{9C78C56E-7738-4D3B-9722-67A4CB028A75}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{A0CBF252-A093-4448-BC10-1A1EF10DB64E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Cover|Any CPU = Cover|Any CPU
Expand Down Expand Up @@ -143,6 +149,17 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{4C3B3EC4-5702-469E-800E-313FB27A0A2B} = {A0CBF252-A093-4448-BC10-1A1EF10DB64E}
{9336E9E7-19BF-49AC-92E3-19FA6B98921E} = {9C78C56E-7738-4D3B-9722-67A4CB028A75}
{BEA6F911-BA98-462C-99AF-3B0595DE2307} = {9C78C56E-7738-4D3B-9722-67A4CB028A75}
{74CEE77F-D2C7-4B8B-9411-8F97F4E803FA} = {9C78C56E-7738-4D3B-9722-67A4CB028A75}
{115A0283-AC42-4D37-97F2-106D168E04D2} = {F7A2F005-3B53-495D-B0EC-CE41FAB4DC75}
{BC17F3EF-FEB4-4186-9342-E2D18F1E56AB} = {F7A2F005-3B53-495D-B0EC-CE41FAB4DC75}
{8EB66613-D5A2-4683-B91A-6AF904FD6B70} = {F7A2F005-3B53-495D-B0EC-CE41FAB4DC75}
{AC76C04B-881E-4CB9-B491-4D19B68459F1} = {F7A2F005-3B53-495D-B0EC-CE41FAB4DC75}
{B210D6E5-7171-4117-9C77-3F2CB59D04D8} = {F7A2F005-3B53-495D-B0EC-CE41FAB4DC75}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {24237160-521B-4CD0-87AB-8994A5E50BE2}
EndGlobalSection
Expand Down
30 changes: 15 additions & 15 deletions Samples/Dapper/DataClasses.cs → Samples/Dapper/Blog.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace ElasticDapper
{
// Let's use the standard blogging class
public class Blog
{
public int BlogId { get; set; }

public string Name { get; set; }

public string Url { get; set; }
}
}
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace ElasticDapper
{
// Let's use the standard blogging class
public class Blog
{
public long BlogId { get; set; }

public string Name { get; set; }

public string Url { get; set; }
}
}
9 changes: 4 additions & 5 deletions Samples/Dapper/ElasticDapper.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
</PropertyGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Build.props))\Build.props" />
<ItemGroup>
<PackageReference Include="EnterpriseLibrary.TransientFaultHandling.Data.NetCore" Version="6.0.1312" />
<PackageReference Include="EnterpriseLibrary.TransientFaultHandling.NetCore" Version="6.0.1312" />
<PackageReference Include="Microsoft.Azure.SqlDatabase.ElasticScale.Client" version="2.3.0" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="8.0.0" />
<PackageReference Include="Dapper" Version="2.1.28" />
<PackageReference Include="Dapper" Version="2.1.35" />
<PackageReference Include="DapperExtensions" Version="1.7.0" />
</ItemGroup>
<ItemGroup>
<None Include="LICENSE" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Src\ElasticScale.Client\Microsoft.Azure.SqlDatabase.ElasticScale.Client.csproj" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion Samples/Dapper/LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2015 Microsoft
Copyright (c) 2024 Microsoft

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
147 changes: 68 additions & 79 deletions Samples/Dapper/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using Dapper;
using DapperExtensions;
using Microsoft.Azure.SqlDatabase.ElasticScale.ShardManagement;
using Microsoft.Data.SqlClient;

////////////////////////////////////////////////////////////////////////////////////////
// This sample illustrates the adjustments that need to be made to use Dapper
Expand All @@ -28,9 +28,8 @@ internal class Program
private static string s_shardmapmgrdb = "[YourShardMapManagerDatabaseName]";
private static string s_shard1 = "[YourShard01DatabaseName]";
private static string s_shard2 = "[YourShard02DatabaseName]";
private static string s_userName = "YourUserName";
private static string s_password = "YourPassword";
private static string s_applicationName = "ESC_Dapv1.0";
private static SqlAuthenticationMethod s_authenticationMethod = SqlAuthenticationMethod.ActiveDirectoryDefault;

// Just two tenants for now.
// Those we will allocate to shards.
Expand All @@ -39,19 +38,14 @@ internal class Program

public static void Main()
{
SqlConnectionStringBuilder connStrBldr = new SqlConnectionStringBuilder
{
UserID = s_userName,
Password = s_password,
ApplicationName = s_applicationName
};
SqlConnectionStringBuilder connStrBldr = GetConnectionStringBuilder();

// Bootstrap the shard map manager, register shards, and store mappings of tenants to shards
// Note that you can keep working with existing shard maps. There is no need to
// re-create and populate the shard map from scratch every time.
Sharding shardingLayer = new Sharding(s_server, s_shardmapmgrdb, connStrBldr.ConnectionString);
shardingLayer.RegisterNewShard(s_server, s_shard1, connStrBldr.ConnectionString, s_tenantId1);
shardingLayer.RegisterNewShard(s_server, s_shard2, connStrBldr.ConnectionString, s_tenantId2);
shardingLayer.RegisterNewShard(s_server, s_shard1, s_tenantId1);
shardingLayer.RegisterNewShard(s_server, s_shard2, s_tenantId2);

// Create schema on each shard.
foreach (string shard in new[] {s_shard1, s_shard2})
Expand All @@ -67,104 +61,85 @@ 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<Blog> result = sqlconn.Query<Blog>(@"
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<Blog> result = sqlconn.Query<Blog>(@"
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<Blog> result = sqlconn.GetList<Blog>();
Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2);
foreach (var item in result)
{
// Display all Blogs for tenant 2
IEnumerable<Blog> result = sqlconn.GetList<Blog>();
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<Blog> result = sqlconn.GetList<Blog>();
Console.WriteLine("All blogs for tenant id {0}:", s_tenantId2);
foreach (var item in result)
{
// Display all Blogs for tenant 2
IEnumerable<Blog> result = sqlconn.GetList<Blog>();
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();
}

private static void CreateSchema(string shardName)
{
SqlConnectionStringBuilder connStrBldr = new SqlConnectionStringBuilder
{
UserID = s_userName,
Password = s_password,
ApplicationName = s_applicationName,
DataSource = s_server,
InitialCatalog = shardName
};
SqlConnectionStringBuilder connStrBldr = GetConnectionStringBuilder();

connStrBldr.DataSource = s_server;
connStrBldr.InitialCatalog = shardName;

using (SqlConnection conn = new SqlConnection(connStrBldr.ToString()))
{
Expand All @@ -178,5 +153,19 @@ [Url] [nvarchar](max) NULL,
)");
}
}

private static SqlConnectionStringBuilder GetConnectionStringBuilder()
{
var connBuilder = new SqlConnectionStringBuilder
{
Authentication = s_authenticationMethod,
ApplicationName = s_applicationName,
CommandTimeout = 60,
ConnectTimeout = 60,
TrustServerCertificate = true
};

return connBuilder;
}
}
}
20 changes: 10 additions & 10 deletions Samples/Dapper/Sharding.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// 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.Azure.SqlDatabase.ElasticScale.ShardManagement;
using Microsoft.Data.SqlClient;

namespace ElasticDapper
{
Expand All @@ -25,41 +25,41 @@ public Sharding(string smmserver, string smmdatabase, string smmconnstr)
ShardMapManager smm;
if (!ShardMapManagerFactory.TryGetSqlShardMapManager(connStrBldr.ConnectionString, ShardMapManagerLoadPolicy.Lazy, out smm))
{
this.ShardMapManager = ShardMapManagerFactory.CreateSqlShardMapManager(connStrBldr.ConnectionString);
ShardMapManager = ShardMapManagerFactory.CreateSqlShardMapManager(connStrBldr.ConnectionString);
}
else
{
this.ShardMapManager = smm;
ShardMapManager = smm;
}

ListShardMap<int> sm;
if (!ShardMapManager.TryGetListShardMap<int>("ElasticScaleWithDapper", out sm))
{
this.ShardMap = ShardMapManager.CreateListShardMap<int>("ElasticScaleWithDapper");
ShardMap = ShardMapManager.CreateListShardMap<int>("ElasticScaleWithDapper");
}
else
{
this.ShardMap = sm;
ShardMap = sm;
}
}

// Enter a new shard - i.e. an empty database - to the shard map, allocate a first tenant to it
public void RegisterNewShard(string server, string database, string connstr, int key)
public void RegisterNewShard(string server, string database, int key)
{
Shard shard;
ShardLocation shardLocation = new ShardLocation(server, database);

if (!this.ShardMap.TryGetShard(shardLocation, out shard))
if (!ShardMap.TryGetShard(shardLocation, out shard))
{
shard = this.ShardMap.CreateShard(shardLocation);
shard = ShardMap.CreateShard(shardLocation);
}

// Register the mapping of the tenant to the shard in the shard map.
// After this step, DDR on the shard map can be used
PointMapping<int> mapping;
if (!this.ShardMap.TryGetMappingForKey(key, out mapping))
if (!ShardMap.TryGetMappingForKey(key, out mapping))
{
this.ShardMap.CreatePointMapping(key, shard);
ShardMap.CreatePointMapping(key, shard);
}
}
}
Expand Down
Loading

0 comments on commit 8838b77

Please sign in to comment.