Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new SQL Server provider package that uses Microsoft.Data.SqlClient #2063

Merged
merged 35 commits into from
Feb 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
a821503
WIP 1
ErikEJ Nov 25, 2022
7b4b5d3
wip step 2
ErikEJ Nov 25, 2022
9b6e6ee
fix up
ErikEJ Nov 25, 2022
be7574a
add resources
ErikEJ Nov 25, 2022
f374af8
various fixes
ErikEJ Nov 26, 2022
0a60a3a
fix typo
ErikEJ Nov 26, 2022
b6594b5
revert global.json change
ErikEJ Nov 26, 2022
22d1d33
fix build
ErikEJ Nov 26, 2022
77ab988
fix license error ?
ErikEJ Nov 26, 2022
9b235b6
throw on unsupported SQL version
ErikEJ Nov 27, 2022
beeb556
undo global.json
ErikEJ Nov 27, 2022
6be406d
trigger CI
ErikEJ Nov 28, 2022
771866b
undo change
ErikEJ Nov 28, 2022
ff68551
add IsPackable
ErikEJ Nov 29, 2022
15adeec
use longer symbol & fix spacing
ErikEJ Nov 29, 2022
f0798ac
add Copyright
ErikEJ Nov 29, 2022
1014db2
fix global json
ErikEJ Nov 29, 2022
31e6949
fix folder name
ErikEJ Nov 29, 2022
3c50a64
Use inherited properties
ErikEJ Nov 29, 2022
7e4ec7f
add smoke test
ErikEJ Nov 30, 2022
80e3881
fix conflict
ErikEJ Dec 7, 2022
9d3f41b
merge
ErikEJ Dec 7, 2022
a6db00c
Formatting fix and readme updates
ErikEJ Dec 11, 2022
b1032f2
Add test
ErikEJ Dec 23, 2022
87ce8d4
Fix namespace
ErikEJ Dec 28, 2022
da46c44
Update to M.D.S. 5.1
ErikEJ Jan 20, 2023
8e5f102
Enable |DataDirectory|
ErikEJ Jan 31, 2023
60ca800
Thanks @bricelam !!
ErikEJ Feb 2, 2023
2f2388f
Fix nuspec
ErikEJ Feb 2, 2023
301c1e8
Fix nuspec?
ErikEJ Feb 2, 2023
f9aa5d5
Fix nuspec ???
ErikEJ Feb 2, 2023
0ad6093
Getting closer ?
ErikEJ Feb 2, 2023
ba975c1
repeat yourself
ErikEJ Feb 2, 2023
46047fe
Update src/Microsoft.EntityFramework.SqlServer/readme.md
ErikEJ Feb 7, 2023
dbb89d2
Merge branch 'main' into mds
ErikEJ Feb 11, 2023
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
13 changes: 13 additions & 0 deletions EntityFramework.sln
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFramework.SqlServer.I
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFramework.SqlServerCompact.InternalsVisibleTo", "src\EntityFramework.SqlServerCompact\EntityFramework.SqlServerCompact.InternalsVisibleTo.csproj", "{0E08516E-89A5-4C72-BBE2-59AFCD4EF55D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.EntityFramework.SqlServer", "src\Microsoft.EntityFramework.SqlServer\Microsoft.EntityFramework.SqlServer.csproj", "{B3CB15BE-EAEC-426D-856D-FE0F5DE5F282}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicrosoftSqlProviderSmokeTest", "test\MicrosoftSqlProviderSmokeTest\MicrosoftSqlProviderSmokeTest.csproj", "{C45A4930-FF5D-43D7-BE67-997E45534157}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -105,6 +109,14 @@ Global
{0E08516E-89A5-4C72-BBE2-59AFCD4EF55D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E08516E-89A5-4C72-BBE2-59AFCD4EF55D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E08516E-89A5-4C72-BBE2-59AFCD4EF55D}.Release|Any CPU.Build.0 = Release|Any CPU
{B3CB15BE-EAEC-426D-856D-FE0F5DE5F282}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B3CB15BE-EAEC-426D-856D-FE0F5DE5F282}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B3CB15BE-EAEC-426D-856D-FE0F5DE5F282}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B3CB15BE-EAEC-426D-856D-FE0F5DE5F282}.Release|Any CPU.Build.0 = Release|Any CPU
{C45A4930-FF5D-43D7-BE67-997E45534157}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C45A4930-FF5D-43D7-BE67-997E45534157}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C45A4930-FF5D-43D7-BE67-997E45534157}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C45A4930-FF5D-43D7-BE67-997E45534157}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -120,6 +132,7 @@ Global
{A92C22F0-200B-4C61-8544-0EAE620B8006} = {24A9C4D1-E189-4D3A-A2D7-36D3ED51D277}
{63368BF7-E04A-4F0E-ACE7-3CC6DE7F3E93} = {A92C22F0-200B-4C61-8544-0EAE620B8006}
{0E08516E-89A5-4C72-BBE2-59AFCD4EF55D} = {A92C22F0-200B-4C61-8544-0EAE620B8006}
{C45A4930-FF5D-43D7-BE67-997E45534157} = {24A9C4D1-E189-4D3A-A2D7-36D3ED51D277}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D7045317-2675-4853-926A-4D4354176EEE}
Expand Down
2 changes: 2 additions & 0 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@
<MicrosoftBuildUtilitiesCoreVersion>16.0.461</MicrosoftBuildUtilitiesCoreVersion>
<MicrosoftSqlServerCompactVersion>4.0.8876.1</MicrosoftSqlServerCompactVersion>
<MicrosoftSqlServerTypesVersion>14.0.1016.290</MicrosoftSqlServerTypesVersion>
<MicrosoftSqlServerTypesXplatVersion>160.1000.6</MicrosoftSqlServerTypesXplatVersion>
<MoqVersion>4.7.145</MoqVersion>
<MySqlDataEntityVersion>6.7.2-beta-ef6</MySqlDataEntityVersion>
<MicrosoftCSharpVersion>4.7.0</MicrosoftCSharpVersion>
<SystemCodeDomVersion>4.7.0</SystemCodeDomVersion>
<SystemComponentModelAnnotationsVersion>4.7.0</SystemComponentModelAnnotationsVersion>
<SystemConfigurationConfigurationManagerVersion>4.7.0</SystemConfigurationConfigurationManagerVersion>
<SystemDataSqlClientVersion>4.8.5</SystemDataSqlClientVersion>
<MicrosoftDataSqlClientVersion>5.1.0</MicrosoftDataSqlClientVersion>
<MicrosoftNETCoreAppInternalPackageVersion>3.1.0-rtm.19565.2</MicrosoftNETCoreAppInternalPackageVersion>
<MicrosoftNETCoreAppRefPackageVersion>3.1.0</MicrosoftNETCoreAppRefPackageVersion>
<MicrosoftNETCoreAppRuntimewinx64PackageVersion>3.1.1</MicrosoftNETCoreAppRuntimewinx64PackageVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -506,12 +506,19 @@ internal sealed class EntityRes
private static EntityRes loader;
private readonly ResourceManager resources;

#if USES_MICROSOFT_DATA_SQLCLIENT
private EntityRes()
{
resources = new ResourceManager(
"System.Data.Entity.SqlServer.Properties.Resources.SqlServer", typeof(System.Data.Entity.SqlServer.MicrosoftSqlProviderServices).Assembly());
}
#else
private EntityRes()
{
resources = new ResourceManager(
"System.Data.Entity.SqlServer.Properties.Resources.SqlServer", typeof(System.Data.Entity.SqlServer.SqlProviderServices).Assembly());
}

#endif
private static EntityRes GetLoader()
{
if (loader == null)
Expand Down
30 changes: 29 additions & 1 deletion src/EntityFramework.SqlServer/SqlAzureExecutionStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
namespace System.Data.Entity.SqlServer
{
using System.Data.Entity.Infrastructure;
#if USES_MICROSOFT_DATA_SQLCLIENT
using Microsoft.Data.SqlClient;
#else
using System.Data.SqlClient;
#endif

/// <summary>
/// An <see cref="IDbExecutionStrategy"/> that retries actions that throw exceptions caused by SQL Azure transient failures.
Expand All @@ -13,26 +17,50 @@ namespace System.Data.Entity.SqlServer
/// if the <see cref="SqlException.Errors"/> contains any of the following error numbers:
/// 40613, 40501, 40197, 10929, 10928, 10060, 10054, 10053, 233, 64 and 20
/// </remarks>
#if USES_MICROSOFT_DATA_SQLCLIENT
public class MicrosoftSqlAzureExecutionStrategy : DbExecutionStrategy
#else
public class SqlAzureExecutionStrategy : DbExecutionStrategy
#endif
{
#if USES_MICROSOFT_DATA_SQLCLIENT
/// <summary>
/// Creates a new instance of <see cref="MicrosoftSqlAzureExecutionStrategy" />.
/// </summary>
/// <remarks>
/// The default retry limit is 5, which means that the total amount of time spent between retries is 26 seconds plus the random factor.
/// </remarks>
public MicrosoftSqlAzureExecutionStrategy()
#else
/// <summary>
/// Creates a new instance of <see cref="SqlAzureExecutionStrategy" />.
/// </summary>
/// <remarks>
/// The default retry limit is 5, which means that the total amount of time spent between retries is 26 seconds plus the random factor.
/// </remarks>
public SqlAzureExecutionStrategy()
#endif
{
}

#if USES_MICROSOFT_DATA_SQLCLIENT
/// <summary>
/// Creates a new instance of <see cref="MicrosoftSqlAzureExecutionStrategy" /> with the specified limits for
/// number of retries and the delay between retries.
/// </summary>
/// <param name="maxRetryCount"> The maximum number of retry attempts. </param>
/// <param name="maxDelay"> The maximum delay in milliseconds between retries. </param>
public MicrosoftSqlAzureExecutionStrategy(int maxRetryCount, TimeSpan maxDelay)
#else
/// <summary>
/// Creates a new instance of <see cref="SqlAzureExecutionStrategy" /> with the specified limits for
/// number of retries and the delay between retries.
/// </summary>
/// <param name="maxRetryCount"> The maximum number of retry attempts. </param>
/// <param name="maxDelay"> The maximum delay in milliseconds between retries. </param>
public SqlAzureExecutionStrategy(int maxRetryCount, TimeSpan maxDelay)
:base(maxRetryCount, maxDelay)
#endif
: base(maxRetryCount, maxDelay)
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

namespace System.Data.Entity.SqlServer
{
#if USES_MICROSOFT_DATA_SQLCLIENT
using Microsoft.Data.SqlClient;
#else
using System.Data.SqlClient;
#endif
using System.Diagnostics.CodeAnalysis;

// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ namespace System.Data.Entity.SqlServer.SqlGen
using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.SqlServer.Utilities;
#if USES_MICROSOFT_DATA_SQLCLIENT
using Microsoft.Data.SqlClient;
#else
using System.Data.SqlClient;
#endif
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
Expand Down
13 changes: 13 additions & 0 deletions src/EntityFramework.SqlServer/SqlGen/DmlSqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ namespace System.Data.Entity.SqlServer.SqlGen
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.SqlServer.Resources;
using System.Data.Entity.SqlServer.Utilities;
#if USES_MICROSOFT_DATA_SQLCLIENT
using Microsoft.Data.SqlClient;
#else
using System.Data.SqlClient;
#endif
using System.Diagnostics;
using System.Globalization;
using System.Linq;
Expand Down Expand Up @@ -490,7 +494,11 @@ internal static void GenerateReturningSql(

private static bool IsValidScopeIdentityColumnType(TypeUsage typeUsage)
{
#if USES_MICROSOFT_DATA_SQLCLIENT
if (!MicrosoftSqlProviderServices.UseScopeIdentity)
#else
if (!SqlProviderServices.UseScopeIdentity)
#endif
{
return false;
}
Expand Down Expand Up @@ -596,8 +604,13 @@ internal SqlParameter CreateParameter(object value, TypeUsage type, string name
// SqlClient will silently truncate data when SqlParameter.Size < |SqlParameter.Value|.
const bool preventTruncation = true;

#if USES_MICROSOFT_DATA_SQLCLIENT
var parameter = MicrosoftSqlProviderServices.CreateSqlParameter(
name ?? GetParameterName(_parameters.Count), type, ParameterMode.In, value, preventTruncation, _sqlGenerator.SqlVersion);
#else
var parameter = SqlProviderServices.CreateSqlParameter(
name ?? GetParameterName(_parameters.Count), type, ParameterMode.In, value, preventTruncation, _sqlGenerator.SqlVersion);
#endif

_parameters.Add(parameter);

Expand Down
12 changes: 10 additions & 2 deletions src/EntityFramework.SqlServer/SqlGen/SqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ namespace System.Data.Entity.SqlServer.SqlGen
using System.Data.Entity.Spatial;
using System.Data.Entity.SqlServer.Resources;
using System.Data.Entity.SqlServer.Utilities;
#if USES_MICROSOFT_DATA_SQLCLIENT
using Microsoft.Data.SqlClient;
#else
using System.Data.SqlClient;
#endif
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
Expand Down Expand Up @@ -2576,9 +2580,13 @@ public override ISqlFragment Visit(DbSkipExpression e)
input.Select.Skip = new SkipClause(HandleCountExpression(e.Count));

// Add the ORDER BY part.
#if USES_MICROSOFT_DATA_SQLCLIENT
if (MicrosoftSqlProviderServices.UseRowNumberOrderingInOffsetQueries)
#else
if (SqlProviderServices.UseRowNumberOrderingInOffsetQueries)
{
input.OrderBy.Append("row_number() OVER (ORDER BY ");
#endif
{
input.OrderBy.Append("row_number() OVER (ORDER BY ");
AddSortKeys(input.OrderBy, e.SortOrder);
input.OrderBy.Append(")");
}
Expand Down
68 changes: 68 additions & 0 deletions src/EntityFramework.SqlServer/SqlProviderServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,38 @@ namespace System.Data.Entity.SqlServer
using System.Data.Entity.SqlServer.Resources;
using System.Data.Entity.SqlServer.SqlGen;
using System.Data.Entity.SqlServer.Utilities;
#if USES_MICROSOFT_DATA_SQLCLIENT
using Microsoft.Data.SqlClient;
#else
using System.Data.SqlClient;
#endif
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;

#if USES_MICROSOFT_DATA_SQLCLIENT
/// <summary>
/// The DbProviderServices implementation for the Microsoft.Data.SqlClient provider for SQL Server.
/// </summary>
/// <remarks>
/// Note that instance of this type also resolve additional provider services for Microsoft SQL Server
/// when this type is registered as an EF provider either using an entry in the application's config file
/// or through code-based registration in <see cref="DbConfiguration" />.
/// The services resolved are:
/// Requests for <see cref="IDbConnectionFactory" /> are resolved to a Singleton instance of
/// <see cref="System.Data.Entity.Infrastructure.MicrosoftLocalDbConnectionFactory" /> to create connections to LocalDB by default.
/// Requests for <see cref="Func{IDbExecutionStrategy}" /> for the invariant name "Microsoft.Data.SqlClient"
/// for any server name are resolved to a delegate that returns a <see cref="DefaultSqlExecutionStrategy" />
/// to provide a non-retrying policy for SQL Server.
/// Requests for <see cref="MigrationSqlGenerator" /> for the invariant name "Microsoft.Data.SqlClient" are
/// resolved to <see cref="MicrosoftSqlServerMigrationSqlGenerator" /> instances to provide default Migrations SQL
/// generation for SQL Server.
/// Requests for <see cref="DbSpatialServices" /> for the invariant name "Microsoft.Data.SqlClient" are
/// resolved to a Singleton instance of <see cref="MicrosoftSqlSpatialServices" /> to provide default spatial
/// services for SQL Server.
/// </remarks>
#else
/// <summary>
/// The DbProviderServices implementation for the SqlClient provider for SQL Server.
/// </summary>
Expand All @@ -44,33 +70,56 @@ namespace System.Data.Entity.SqlServer
/// resolved to a Singleton instance of <see cref="SqlSpatialServices" /> to provide default spatial
/// services for SQL Server.
/// </remarks>
#endif
[SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")]
#if USES_MICROSOFT_DATA_SQLCLIENT
public sealed class MicrosoftSqlProviderServices : DbProviderServices
#else
public sealed class SqlProviderServices : DbProviderServices
#endif
{
/// <summary>
/// This is the well-known string using in configuration files and code-based configuration as
/// the "provider invariant name" used to specify Microsoft SQL Server for ADO.NET and
/// Entity Framework provider services.
/// </summary>
#if USES_MICROSOFT_DATA_SQLCLIENT
public const string ProviderInvariantName = "Microsoft.Data.SqlClient";
#else
public const string ProviderInvariantName = "System.Data.SqlClient";
#endif

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

// <summary>
// Private constructor to ensure only Singleton instance is created.
// </summary>
#if USES_MICROSOFT_DATA_SQLCLIENT
private MicrosoftSqlProviderServices()
#else
private SqlProviderServices()
#endif
{
#if USES_MICROSOFT_DATA_SQLCLIENT
AddDependencyResolver(new SingletonDependencyResolver<IDbConnectionFactory>(new MicrosoftLocalDbConnectionFactory()));
#else
AddDependencyResolver(new SingletonDependencyResolver<IDbConnectionFactory>(new LocalDbConnectionFactory()));
#endif

AddDependencyResolver(
new ExecutionStrategyResolver<DefaultSqlExecutionStrategy>(
ProviderInvariantName, null, () => new DefaultSqlExecutionStrategy()));

#if USES_MICROSOFT_DATA_SQLCLIENT
AddDependencyResolver(
new SingletonDependencyResolver<Func<MigrationSqlGenerator>>(
() => new MicrosoftSqlServerMigrationSqlGenerator(), ProviderInvariantName));
#else
AddDependencyResolver(
new SingletonDependencyResolver<Func<MigrationSqlGenerator>>(
() => new SqlServerMigrationSqlGenerator(), ProviderInvariantName));
#endif

AddDependencyResolver(
new SingletonDependencyResolver<TableExistenceChecker>(
Expand All @@ -80,7 +129,11 @@ private SqlProviderServices()
// or if a key was provided and the invariant name matches.
AddDependencyResolver(
new SingletonDependencyResolver<DbSpatialServices>(
#if USES_MICROSOFT_DATA_SQLCLIENT
MicrosoftSqlSpatialServices.Instance,
#else
SqlSpatialServices.Instance,
#endif
k =>
{
if (k == null)
Expand All @@ -98,7 +151,11 @@ private SqlProviderServices()
// <summary>
// Singleton object
// </summary>
#if USES_MICROSOFT_DATA_SQLCLIENT
private static readonly MicrosoftSqlProviderServices _providerInstance = new MicrosoftSqlProviderServices();
#else
private static readonly SqlProviderServices _providerInstance = new SqlProviderServices();
#endif

private static bool _truncateDecimalsToScale = true;
private static bool _useScopeIdentity = true;
Expand All @@ -107,7 +164,11 @@ private SqlProviderServices()
/// <summary>
/// The Singleton instance of the SqlProviderServices type.
/// </summary>
#if USES_MICROSOFT_DATA_SQLCLIENT
public static MicrosoftSqlProviderServices Instance
#else
public static SqlProviderServices Instance
#endif
{
get { return _providerInstance; }
}
Expand Down Expand Up @@ -512,9 +573,16 @@ protected override DbSpatialDataReader GetDbSpatialDataReader(DbDataReader fromR
"Return DbSpatialServices from the GetService method. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.")]
protected override DbSpatialServices DbGetSpatialServices(string versionHint)
{
#if USES_MICROSOFT_DATA_SQLCLIENT
return SupportsSpatial(versionHint)
? MicrosoftSqlSpatialServices.Instance
: null;

#else
return SupportsSpatial(versionHint)
? SqlSpatialServices.Instance
: null;
#endif
}

private static bool SupportsSpatial(string versionHint)
Expand Down
4 changes: 4 additions & 0 deletions src/EntityFramework.SqlServer/SqlProviderUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ namespace System.Data.Entity.SqlServer
{
using System.Data.Common;
using System.Data.Entity.SqlServer.Resources;
#if USES_MICROSOFT_DATA_SQLCLIENT
using Microsoft.Data.SqlClient;
#else
using System.Data.SqlClient;
#endif

internal class SqlProviderUtilities
{
Expand Down
Loading