Skip to content

Commit be77956

Browse files
ErikEJajcvickers
andauthored
Add new SQL Server provider package that uses Microsoft.Data.SqlClient (#2063)
Co-authored-by: Arthur Vickers <[email protected]>
1 parent bbebbd2 commit be77956

24 files changed

+2603
-5
lines changed

EntityFramework.sln

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFramework.SqlServer.I
4343
EndProject
4444
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFramework.SqlServerCompact.InternalsVisibleTo", "src\EntityFramework.SqlServerCompact\EntityFramework.SqlServerCompact.InternalsVisibleTo.csproj", "{0E08516E-89A5-4C72-BBE2-59AFCD4EF55D}"
4545
EndProject
46+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.EntityFramework.SqlServer", "src\Microsoft.EntityFramework.SqlServer\Microsoft.EntityFramework.SqlServer.csproj", "{B3CB15BE-EAEC-426D-856D-FE0F5DE5F282}"
47+
EndProject
48+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicrosoftSqlProviderSmokeTest", "test\MicrosoftSqlProviderSmokeTest\MicrosoftSqlProviderSmokeTest.csproj", "{C45A4930-FF5D-43D7-BE67-997E45534157}"
49+
EndProject
4650
Global
4751
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4852
Debug|Any CPU = Debug|Any CPU
@@ -105,6 +109,14 @@ Global
105109
{0E08516E-89A5-4C72-BBE2-59AFCD4EF55D}.Debug|Any CPU.Build.0 = Debug|Any CPU
106110
{0E08516E-89A5-4C72-BBE2-59AFCD4EF55D}.Release|Any CPU.ActiveCfg = Release|Any CPU
107111
{0E08516E-89A5-4C72-BBE2-59AFCD4EF55D}.Release|Any CPU.Build.0 = Release|Any CPU
112+
{B3CB15BE-EAEC-426D-856D-FE0F5DE5F282}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
113+
{B3CB15BE-EAEC-426D-856D-FE0F5DE5F282}.Debug|Any CPU.Build.0 = Debug|Any CPU
114+
{B3CB15BE-EAEC-426D-856D-FE0F5DE5F282}.Release|Any CPU.ActiveCfg = Release|Any CPU
115+
{B3CB15BE-EAEC-426D-856D-FE0F5DE5F282}.Release|Any CPU.Build.0 = Release|Any CPU
116+
{C45A4930-FF5D-43D7-BE67-997E45534157}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
117+
{C45A4930-FF5D-43D7-BE67-997E45534157}.Debug|Any CPU.Build.0 = Debug|Any CPU
118+
{C45A4930-FF5D-43D7-BE67-997E45534157}.Release|Any CPU.ActiveCfg = Release|Any CPU
119+
{C45A4930-FF5D-43D7-BE67-997E45534157}.Release|Any CPU.Build.0 = Release|Any CPU
108120
EndGlobalSection
109121
GlobalSection(SolutionProperties) = preSolution
110122
HideSolutionNode = FALSE
@@ -120,6 +132,7 @@ Global
120132
{A92C22F0-200B-4C61-8544-0EAE620B8006} = {24A9C4D1-E189-4D3A-A2D7-36D3ED51D277}
121133
{63368BF7-E04A-4F0E-ACE7-3CC6DE7F3E93} = {A92C22F0-200B-4C61-8544-0EAE620B8006}
122134
{0E08516E-89A5-4C72-BBE2-59AFCD4EF55D} = {A92C22F0-200B-4C61-8544-0EAE620B8006}
135+
{C45A4930-FF5D-43D7-BE67-997E45534157} = {24A9C4D1-E189-4D3A-A2D7-36D3ED51D277}
123136
EndGlobalSection
124137
GlobalSection(ExtensibilityGlobals) = postSolution
125138
SolutionGuid = {D7045317-2675-4853-926A-4D4354176EEE}

eng/Versions.props

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818
<MicrosoftBuildUtilitiesCoreVersion>16.0.461</MicrosoftBuildUtilitiesCoreVersion>
1919
<MicrosoftSqlServerCompactVersion>4.0.8876.1</MicrosoftSqlServerCompactVersion>
2020
<MicrosoftSqlServerTypesVersion>14.0.1016.290</MicrosoftSqlServerTypesVersion>
21+
<MicrosoftSqlServerTypesXplatVersion>160.1000.6</MicrosoftSqlServerTypesXplatVersion>
2122
<MoqVersion>4.7.145</MoqVersion>
2223
<MySqlDataEntityVersion>6.7.2-beta-ef6</MySqlDataEntityVersion>
2324
<MicrosoftCSharpVersion>4.7.0</MicrosoftCSharpVersion>
2425
<SystemCodeDomVersion>4.7.0</SystemCodeDomVersion>
2526
<SystemComponentModelAnnotationsVersion>4.7.0</SystemComponentModelAnnotationsVersion>
2627
<SystemConfigurationConfigurationManagerVersion>4.7.0</SystemConfigurationConfigurationManagerVersion>
2728
<SystemDataSqlClientVersion>4.8.5</SystemDataSqlClientVersion>
29+
<MicrosoftDataSqlClientVersion>5.1.0</MicrosoftDataSqlClientVersion>
2830
<MicrosoftNETCoreAppInternalPackageVersion>3.1.0-rtm.19565.2</MicrosoftNETCoreAppInternalPackageVersion>
2931
<MicrosoftNETCoreAppRefPackageVersion>3.1.0</MicrosoftNETCoreAppRefPackageVersion>
3032
<MicrosoftNETCoreAppRuntimewinx64PackageVersion>3.1.1</MicrosoftNETCoreAppRuntimewinx64PackageVersion>

src/EntityFramework.SqlServer/Properties/Resources.SqlServer.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,12 +506,19 @@ internal sealed class EntityRes
506506
private static EntityRes loader;
507507
private readonly ResourceManager resources;
508508

509+
#if USES_MICROSOFT_DATA_SQLCLIENT
510+
private EntityRes()
511+
{
512+
resources = new ResourceManager(
513+
"System.Data.Entity.SqlServer.Properties.Resources.SqlServer", typeof(System.Data.Entity.SqlServer.MicrosoftSqlProviderServices).Assembly());
514+
}
515+
#else
509516
private EntityRes()
510517
{
511518
resources = new ResourceManager(
512519
"System.Data.Entity.SqlServer.Properties.Resources.SqlServer", typeof(System.Data.Entity.SqlServer.SqlProviderServices).Assembly());
513520
}
514-
521+
#endif
515522
private static EntityRes GetLoader()
516523
{
517524
if (loader == null)

src/EntityFramework.SqlServer/SqlAzureExecutionStrategy.cs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
namespace System.Data.Entity.SqlServer
44
{
55
using System.Data.Entity.Infrastructure;
6+
#if USES_MICROSOFT_DATA_SQLCLIENT
7+
using Microsoft.Data.SqlClient;
8+
#else
69
using System.Data.SqlClient;
10+
#endif
711

812
/// <summary>
913
/// An <see cref="IDbExecutionStrategy"/> that retries actions that throw exceptions caused by SQL Azure transient failures.
@@ -13,26 +17,50 @@ namespace System.Data.Entity.SqlServer
1317
/// if the <see cref="SqlException.Errors"/> contains any of the following error numbers:
1418
/// 40613, 40501, 40197, 10929, 10928, 10060, 10054, 10053, 233, 64 and 20
1519
/// </remarks>
20+
#if USES_MICROSOFT_DATA_SQLCLIENT
21+
public class MicrosoftSqlAzureExecutionStrategy : DbExecutionStrategy
22+
#else
1623
public class SqlAzureExecutionStrategy : DbExecutionStrategy
24+
#endif
1725
{
26+
#if USES_MICROSOFT_DATA_SQLCLIENT
27+
/// <summary>
28+
/// Creates a new instance of <see cref="MicrosoftSqlAzureExecutionStrategy" />.
29+
/// </summary>
30+
/// <remarks>
31+
/// The default retry limit is 5, which means that the total amount of time spent between retries is 26 seconds plus the random factor.
32+
/// </remarks>
33+
public MicrosoftSqlAzureExecutionStrategy()
34+
#else
1835
/// <summary>
1936
/// Creates a new instance of <see cref="SqlAzureExecutionStrategy" />.
2037
/// </summary>
2138
/// <remarks>
2239
/// The default retry limit is 5, which means that the total amount of time spent between retries is 26 seconds plus the random factor.
2340
/// </remarks>
2441
public SqlAzureExecutionStrategy()
42+
#endif
2543
{
2644
}
2745

46+
#if USES_MICROSOFT_DATA_SQLCLIENT
47+
/// <summary>
48+
/// Creates a new instance of <see cref="MicrosoftSqlAzureExecutionStrategy" /> with the specified limits for
49+
/// number of retries and the delay between retries.
50+
/// </summary>
51+
/// <param name="maxRetryCount"> The maximum number of retry attempts. </param>
52+
/// <param name="maxDelay"> The maximum delay in milliseconds between retries. </param>
53+
public MicrosoftSqlAzureExecutionStrategy(int maxRetryCount, TimeSpan maxDelay)
54+
#else
2855
/// <summary>
2956
/// Creates a new instance of <see cref="SqlAzureExecutionStrategy" /> with the specified limits for
3057
/// number of retries and the delay between retries.
3158
/// </summary>
3259
/// <param name="maxRetryCount"> The maximum number of retry attempts. </param>
3360
/// <param name="maxDelay"> The maximum delay in milliseconds between retries. </param>
3461
public SqlAzureExecutionStrategy(int maxRetryCount, TimeSpan maxDelay)
35-
:base(maxRetryCount, maxDelay)
62+
#endif
63+
: base(maxRetryCount, maxDelay)
3664
{
3765
}
3866

src/EntityFramework.SqlServer/SqlAzureRetriableExceptionDetector.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
namespace System.Data.Entity.SqlServer
44
{
5+
#if USES_MICROSOFT_DATA_SQLCLIENT
6+
using Microsoft.Data.SqlClient;
7+
#else
58
using System.Data.SqlClient;
9+
#endif
610
using System.Diagnostics.CodeAnalysis;
711

812
// <summary>

src/EntityFramework.SqlServer/SqlGen/DmlFunctionSqlGenerator.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ namespace System.Data.Entity.SqlServer.SqlGen
77
using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder;
88
using System.Data.Entity.Core.Metadata.Edm;
99
using System.Data.Entity.SqlServer.Utilities;
10+
#if USES_MICROSOFT_DATA_SQLCLIENT
11+
using Microsoft.Data.SqlClient;
12+
#else
1013
using System.Data.SqlClient;
14+
#endif
1115
using System.Diagnostics.CodeAnalysis;
1216
using System.Linq;
1317
using System.Text;

src/EntityFramework.SqlServer/SqlGen/DmlSqlGenerator.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ namespace System.Data.Entity.SqlServer.SqlGen
99
using System.Data.Entity.Core.Metadata.Edm;
1010
using System.Data.Entity.SqlServer.Resources;
1111
using System.Data.Entity.SqlServer.Utilities;
12+
#if USES_MICROSOFT_DATA_SQLCLIENT
13+
using Microsoft.Data.SqlClient;
14+
#else
1215
using System.Data.SqlClient;
16+
#endif
1317
using System.Diagnostics;
1418
using System.Globalization;
1519
using System.Linq;
@@ -490,7 +494,11 @@ internal static void GenerateReturningSql(
490494

491495
private static bool IsValidScopeIdentityColumnType(TypeUsage typeUsage)
492496
{
497+
#if USES_MICROSOFT_DATA_SQLCLIENT
498+
if (!MicrosoftSqlProviderServices.UseScopeIdentity)
499+
#else
493500
if (!SqlProviderServices.UseScopeIdentity)
501+
#endif
494502
{
495503
return false;
496504
}
@@ -596,8 +604,13 @@ internal SqlParameter CreateParameter(object value, TypeUsage type, string name
596604
// SqlClient will silently truncate data when SqlParameter.Size < |SqlParameter.Value|.
597605
const bool preventTruncation = true;
598606

607+
#if USES_MICROSOFT_DATA_SQLCLIENT
608+
var parameter = MicrosoftSqlProviderServices.CreateSqlParameter(
609+
name ?? GetParameterName(_parameters.Count), type, ParameterMode.In, value, preventTruncation, _sqlGenerator.SqlVersion);
610+
#else
599611
var parameter = SqlProviderServices.CreateSqlParameter(
600612
name ?? GetParameterName(_parameters.Count), type, ParameterMode.In, value, preventTruncation, _sqlGenerator.SqlVersion);
613+
#endif
601614

602615
_parameters.Add(parameter);
603616

src/EntityFramework.SqlServer/SqlGen/SqlGenerator.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ namespace System.Data.Entity.SqlServer.SqlGen
1212
using System.Data.Entity.Spatial;
1313
using System.Data.Entity.SqlServer.Resources;
1414
using System.Data.Entity.SqlServer.Utilities;
15+
#if USES_MICROSOFT_DATA_SQLCLIENT
16+
using Microsoft.Data.SqlClient;
17+
#else
1518
using System.Data.SqlClient;
19+
#endif
1620
using System.Diagnostics;
1721
using System.Diagnostics.CodeAnalysis;
1822
using System.Globalization;
@@ -2576,9 +2580,13 @@ public override ISqlFragment Visit(DbSkipExpression e)
25762580
input.Select.Skip = new SkipClause(HandleCountExpression(e.Count));
25772581

25782582
// Add the ORDER BY part.
2583+
#if USES_MICROSOFT_DATA_SQLCLIENT
2584+
if (MicrosoftSqlProviderServices.UseRowNumberOrderingInOffsetQueries)
2585+
#else
25792586
if (SqlProviderServices.UseRowNumberOrderingInOffsetQueries)
2580-
{
2581-
input.OrderBy.Append("row_number() OVER (ORDER BY ");
2587+
#endif
2588+
{
2589+
input.OrderBy.Append("row_number() OVER (ORDER BY ");
25822590
AddSortKeys(input.OrderBy, e.SortOrder);
25832591
input.OrderBy.Append(")");
25842592
}

src/EntityFramework.SqlServer/SqlProviderServices.cs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,38 @@ namespace System.Data.Entity.SqlServer
1818
using System.Data.Entity.SqlServer.Resources;
1919
using System.Data.Entity.SqlServer.SqlGen;
2020
using System.Data.Entity.SqlServer.Utilities;
21+
#if USES_MICROSOFT_DATA_SQLCLIENT
22+
using Microsoft.Data.SqlClient;
23+
#else
2124
using System.Data.SqlClient;
25+
#endif
2226
using System.Diagnostics;
2327
using System.Diagnostics.CodeAnalysis;
2428
using System.Globalization;
2529
using System.IO;
2630

31+
#if USES_MICROSOFT_DATA_SQLCLIENT
32+
/// <summary>
33+
/// The DbProviderServices implementation for the Microsoft.Data.SqlClient provider for SQL Server.
34+
/// </summary>
35+
/// <remarks>
36+
/// Note that instance of this type also resolve additional provider services for Microsoft SQL Server
37+
/// when this type is registered as an EF provider either using an entry in the application's config file
38+
/// or through code-based registration in <see cref="DbConfiguration" />.
39+
/// The services resolved are:
40+
/// Requests for <see cref="IDbConnectionFactory" /> are resolved to a Singleton instance of
41+
/// <see cref="System.Data.Entity.Infrastructure.MicrosoftLocalDbConnectionFactory" /> to create connections to LocalDB by default.
42+
/// Requests for <see cref="Func{IDbExecutionStrategy}" /> for the invariant name "Microsoft.Data.SqlClient"
43+
/// for any server name are resolved to a delegate that returns a <see cref="DefaultSqlExecutionStrategy" />
44+
/// to provide a non-retrying policy for SQL Server.
45+
/// Requests for <see cref="MigrationSqlGenerator" /> for the invariant name "Microsoft.Data.SqlClient" are
46+
/// resolved to <see cref="MicrosoftSqlServerMigrationSqlGenerator" /> instances to provide default Migrations SQL
47+
/// generation for SQL Server.
48+
/// Requests for <see cref="DbSpatialServices" /> for the invariant name "Microsoft.Data.SqlClient" are
49+
/// resolved to a Singleton instance of <see cref="MicrosoftSqlSpatialServices" /> to provide default spatial
50+
/// services for SQL Server.
51+
/// </remarks>
52+
#else
2753
/// <summary>
2854
/// The DbProviderServices implementation for the SqlClient provider for SQL Server.
2955
/// </summary>
@@ -44,33 +70,56 @@ namespace System.Data.Entity.SqlServer
4470
/// resolved to a Singleton instance of <see cref="SqlSpatialServices" /> to provide default spatial
4571
/// services for SQL Server.
4672
/// </remarks>
73+
#endif
4774
[SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")]
75+
#if USES_MICROSOFT_DATA_SQLCLIENT
76+
public sealed class MicrosoftSqlProviderServices : DbProviderServices
77+
#else
4878
public sealed class SqlProviderServices : DbProviderServices
79+
#endif
4980
{
5081
/// <summary>
5182
/// This is the well-known string using in configuration files and code-based configuration as
5283
/// the "provider invariant name" used to specify Microsoft SQL Server for ADO.NET and
5384
/// Entity Framework provider services.
5485
/// </summary>
86+
#if USES_MICROSOFT_DATA_SQLCLIENT
87+
public const string ProviderInvariantName = "Microsoft.Data.SqlClient";
88+
#else
5589
public const string ProviderInvariantName = "System.Data.SqlClient";
90+
#endif
5691

5792
private ConcurrentDictionary<string, SqlProviderManifest> _providerManifests =
5893
new ConcurrentDictionary<string, SqlProviderManifest>();
5994

6095
// <summary>
6196
// Private constructor to ensure only Singleton instance is created.
6297
// </summary>
98+
#if USES_MICROSOFT_DATA_SQLCLIENT
99+
private MicrosoftSqlProviderServices()
100+
#else
63101
private SqlProviderServices()
102+
#endif
64103
{
104+
#if USES_MICROSOFT_DATA_SQLCLIENT
105+
AddDependencyResolver(new SingletonDependencyResolver<IDbConnectionFactory>(new MicrosoftLocalDbConnectionFactory()));
106+
#else
65107
AddDependencyResolver(new SingletonDependencyResolver<IDbConnectionFactory>(new LocalDbConnectionFactory()));
108+
#endif
66109

67110
AddDependencyResolver(
68111
new ExecutionStrategyResolver<DefaultSqlExecutionStrategy>(
69112
ProviderInvariantName, null, () => new DefaultSqlExecutionStrategy()));
70113

114+
#if USES_MICROSOFT_DATA_SQLCLIENT
115+
AddDependencyResolver(
116+
new SingletonDependencyResolver<Func<MigrationSqlGenerator>>(
117+
() => new MicrosoftSqlServerMigrationSqlGenerator(), ProviderInvariantName));
118+
#else
71119
AddDependencyResolver(
72120
new SingletonDependencyResolver<Func<MigrationSqlGenerator>>(
73121
() => new SqlServerMigrationSqlGenerator(), ProviderInvariantName));
122+
#endif
74123

75124
AddDependencyResolver(
76125
new SingletonDependencyResolver<TableExistenceChecker>(
@@ -80,7 +129,11 @@ private SqlProviderServices()
80129
// or if a key was provided and the invariant name matches.
81130
AddDependencyResolver(
82131
new SingletonDependencyResolver<DbSpatialServices>(
132+
#if USES_MICROSOFT_DATA_SQLCLIENT
133+
MicrosoftSqlSpatialServices.Instance,
134+
#else
83135
SqlSpatialServices.Instance,
136+
#endif
84137
k =>
85138
{
86139
if (k == null)
@@ -98,7 +151,11 @@ private SqlProviderServices()
98151
// <summary>
99152
// Singleton object
100153
// </summary>
154+
#if USES_MICROSOFT_DATA_SQLCLIENT
155+
private static readonly MicrosoftSqlProviderServices _providerInstance = new MicrosoftSqlProviderServices();
156+
#else
101157
private static readonly SqlProviderServices _providerInstance = new SqlProviderServices();
158+
#endif
102159

103160
private static bool _truncateDecimalsToScale = true;
104161
private static bool _useScopeIdentity = true;
@@ -107,7 +164,11 @@ private SqlProviderServices()
107164
/// <summary>
108165
/// The Singleton instance of the SqlProviderServices type.
109166
/// </summary>
167+
#if USES_MICROSOFT_DATA_SQLCLIENT
168+
public static MicrosoftSqlProviderServices Instance
169+
#else
110170
public static SqlProviderServices Instance
171+
#endif
111172
{
112173
get { return _providerInstance; }
113174
}
@@ -512,9 +573,16 @@ protected override DbSpatialDataReader GetDbSpatialDataReader(DbDataReader fromR
512573
"Return DbSpatialServices from the GetService method. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.")]
513574
protected override DbSpatialServices DbGetSpatialServices(string versionHint)
514575
{
576+
#if USES_MICROSOFT_DATA_SQLCLIENT
577+
return SupportsSpatial(versionHint)
578+
? MicrosoftSqlSpatialServices.Instance
579+
: null;
580+
581+
#else
515582
return SupportsSpatial(versionHint)
516583
? SqlSpatialServices.Instance
517584
: null;
585+
#endif
518586
}
519587

520588
private static bool SupportsSpatial(string versionHint)

src/EntityFramework.SqlServer/SqlProviderUtilities.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ namespace System.Data.Entity.SqlServer
44
{
55
using System.Data.Common;
66
using System.Data.Entity.SqlServer.Resources;
7+
#if USES_MICROSOFT_DATA_SQLCLIENT
8+
using Microsoft.Data.SqlClient;
9+
#else
710
using System.Data.SqlClient;
11+
#endif
812

913
internal class SqlProviderUtilities
1014
{

0 commit comments

Comments
 (0)