diff --git a/src/EFCore.Jet/Infrastructure/Internal/IJetOptions.cs b/src/EFCore.Jet/Infrastructure/Internal/IJetOptions.cs index 566436d..9137fec 100644 --- a/src/EFCore.Jet/Infrastructure/Internal/IJetOptions.cs +++ b/src/EFCore.Jet/Infrastructure/Internal/IJetOptions.cs @@ -12,6 +12,6 @@ namespace EntityFrameworkCore.Jet.Infrastructure.Internal public interface IJetOptions : ISingletonOptions { string ConnectionString { get; } - DataAccessType DataAccessType { get; } + DataAccessProviderType DataAccessProviderType { get; } } } diff --git a/src/EFCore.Jet/Internal/JetOptions.cs b/src/EFCore.Jet/Internal/JetOptions.cs index 0c8fd05..0a56e1c 100644 --- a/src/EFCore.Jet/Internal/JetOptions.cs +++ b/src/EFCore.Jet/Internal/JetOptions.cs @@ -26,7 +26,7 @@ namespace EntityFrameworkCore.Jet.Internal // RowNumberPagingEnabled = jetOptions.RowNumberPaging ?? false; - DataAccessType = GetDataAccessTypeFromOptions(jetOptions); + DataAccessProviderType = GetDataAccessProviderTypeFromOptions(jetOptions); ConnectionString = jetOptions.Connection?.ConnectionString ?? jetOptions.ConnectionString; } @@ -48,7 +48,7 @@ namespace EntityFrameworkCore.Jet.Internal } */ - if (DataAccessType != GetDataAccessTypeFromOptions(jetOptions)) + if (DataAccessProviderType != GetDataAccessProviderTypeFromOptions(jetOptions)) { throw new InvalidOperationException( CoreStrings.SingletonOptionChanged( @@ -57,9 +57,7 @@ namespace EntityFrameworkCore.Jet.Internal } } - private static DataAccessType GetDataAccessTypeFromOptions(JetOptionsExtension jetOptions) - => jetOptions.DataAccessProviderFactory - private static DataAccessProviderType GetDataAccessTypeFromOptions(JetOptionsExtension jetOptions) + private static DataAccessProviderType GetDataAccessProviderTypeFromOptions(JetOptionsExtension jetOptions) { if (jetOptions.DataAccessProviderFactory == null) { @@ -67,12 +65,12 @@ namespace EntityFrameworkCore.Jet.Internal } if (jetOptions.DataAccessProviderFactory - .GetType() - .GetTypesInHierarchy() + .GetType() + .GetTypesInHierarchy() .Any( - t => string.Equals( - t.FullName, - "System.Data.OleDb.OleDbFactory", + t => string.Equals( + t.FullName, + "System.Data.OleDb.OleDbFactory", StringComparison.OrdinalIgnoreCase))) { return DataAccessProviderType.OleDb; @@ -108,7 +106,7 @@ namespace EntityFrameworkCore.Jet.Internal /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual DataAccessType DataAccessType { get; private set; } + public virtual DataAccessProviderType DataAccessProviderType { get; private set; } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Jet/Metadata/Conventions/JetConventionSetBuilder.cs b/src/EFCore.Jet/Metadata/Conventions/JetConventionSetBuilder.cs index a3e188c..0b048bb 100644 --- a/src/EFCore.Jet/Metadata/Conventions/JetConventionSetBuilder.cs +++ b/src/EFCore.Jet/Metadata/Conventions/JetConventionSetBuilder.cs @@ -57,7 +57,7 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Conventions .AddEntityFrameworkJet() .AddDbContext((p, o) => o .UseJetWithoutPredefinedDataAccessProviderFactory( - JetConnection.GetConnectionString("Jet.accdb", DataAccessType.Odbc)) + JetConnection.GetConnectionString("Jet.accdb", DataAccessProviderType.Odbc)) .UseInternalServiceProvider(p)) .BuildServiceProvider(); diff --git a/src/EFCore.Jet/Storage/Internal/JetSqlGenerationHelper.cs b/src/EFCore.Jet/Storage/Internal/JetSqlGenerationHelper.cs index 276ebae..d85e846 100644 --- a/src/EFCore.Jet/Storage/Internal/JetSqlGenerationHelper.cs +++ b/src/EFCore.Jet/Storage/Internal/JetSqlGenerationHelper.cs @@ -92,13 +92,13 @@ namespace EntityFrameworkCore.Jet.Storage.Internal } public override string GenerateParameterNamePlaceholder(string name) - => _jetOptions.DataAccessType == DataAccessType.OleDb + => _jetOptions.DataAccessProviderType == DataAccessProviderType.OleDb ? base.GenerateParameterNamePlaceholder(name) : "?"; public override void GenerateParameterNamePlaceholder(StringBuilder builder, string name) { - if (_jetOptions.DataAccessType == DataAccessType.OleDb) + if (_jetOptions.DataAccessProviderType == DataAccessProviderType.OleDb) { base.GenerateParameterNamePlaceholder(builder, name); } diff --git a/src/EFCore.Jet/Storage/Internal/JetTransientExceptionDetector.cs b/src/EFCore.Jet/Storage/Internal/JetTransientExceptionDetector.cs index 1cc0c71..24e2568 100644 --- a/src/EFCore.Jet/Storage/Internal/JetTransientExceptionDetector.cs +++ b/src/EFCore.Jet/Storage/Internal/JetTransientExceptionDetector.cs @@ -2,7 +2,6 @@ using System; using System.Data.Jet; -using System.Data.OleDb; using JetBrains.Annotations; namespace EntityFrameworkCore.Jet.Storage.Internal @@ -14,14 +13,14 @@ namespace EntityFrameworkCore.Jet.Storage.Internal { public static bool ShouldRetryOn([NotNull] Exception ex) { - DataAccessType dataAccessType; + DataAccessProviderType dataAccessProviderType; var exceptionFullName = ex.GetType().FullName; if (exceptionFullName == "System.Data.OleDb.OleDbException") - dataAccessType = DataAccessType.OleDb; + dataAccessProviderType = DataAccessProviderType.OleDb; else if (exceptionFullName == "System.Data.Odbc.OdbcException") - dataAccessType = DataAccessType.Odbc; + dataAccessProviderType = DataAccessProviderType.Odbc; else return false; @@ -36,7 +35,7 @@ namespace EntityFrameworkCore.Jet.Storage.Internal // If too many commands get executed in short succession, ACE/Jet can run out of table handles. // This can happen despite proper disposal of OdbcCommand and OdbcDataReader objects. // Waiting for a couple of milliseconds will give ACE/Jet enough time to catch up. - case -1311 when dataAccessType == DataAccessType.Odbc: + case -1311 when dataAccessProviderType == DataAccessProviderType.Odbc: return true; } diff --git a/src/System.Data.Jet/AdoxWrapper.cs b/src/System.Data.Jet/AdoxWrapper.cs index b0f9dbe..fd8c857 100644 --- a/src/System.Data.Jet/AdoxWrapper.cs +++ b/src/System.Data.Jet/AdoxWrapper.cs @@ -68,7 +68,9 @@ namespace System.Data.Jet try { - connectionString = JetConnection.GetConnectionString(fileName, DataAccessType.OleDb); + // ADOX is an ADO eXtension and ADO is build on top of OLE DB. We always need to use an OLE DB + // connection string for ADOX. + connectionString = JetConnection.GetConnectionString(fileName, DataAccessProviderType.OleDb); catalog.Create(connectionString) .Dispose(); // Dispose the returned Connection object, because we don't use it here. diff --git a/src/System.Data.Jet/DataAccessType.cs b/src/System.Data.Jet/DataAccessType.cs index 4c46859..aa03d26 100644 --- a/src/System.Data.Jet/DataAccessType.cs +++ b/src/System.Data.Jet/DataAccessType.cs @@ -1,6 +1,6 @@ namespace System.Data.Jet { - public enum DataAccessType + public enum DataAccessProviderType { Odbc, OleDb, diff --git a/src/System.Data.Jet/JetConnection.cs b/src/System.Data.Jet/JetConnection.cs index 31089bb..1decee8 100644 --- a/src/System.Data.Jet/JetConnection.cs +++ b/src/System.Data.Jet/JetConnection.cs @@ -426,21 +426,21 @@ namespace System.Data.Jet => AdoxWrapper.CreateEmptyDatabase(fileName, dataAccessProviderFactory); public static string GetConnectionString(string fileName, DbProviderFactory dataAccessProviderFactory) - => GetConnectionString(fileName, GetDataAccessType(dataAccessProviderFactory)); + => GetConnectionString(fileName, GetDataAccessProviderType(dataAccessProviderFactory)); - public static string GetConnectionString(string fileName, DataAccessType dataAccessType) + public static string GetConnectionString(string fileName, DataAccessProviderType dataAccessProviderType) => GetConnectionString( - dataAccessType == DataAccessType.OleDb + dataAccessProviderType == DataAccessProviderType.OleDb ? JetConfiguration.OleDbDefaultProvider : JetConfiguration.OdbcDefaultProvider, fileName, - dataAccessType); + dataAccessProviderType); public static string GetConnectionString(string provider, string fileName, DbProviderFactory dataAccessProviderFactory) - => GetConnectionString(provider, fileName, GetDataAccessType(dataAccessProviderFactory)); + => GetConnectionString(provider, fileName, GetDataAccessProviderType(dataAccessProviderFactory)); - public static string GetConnectionString(string provider, string fileName, DataAccessType dataAccessType) - => dataAccessType == DataAccessType.OleDb + public static string GetConnectionString(string provider, string fileName, DataAccessProviderType dataAccessProviderType) + => dataAccessProviderType == DataAccessProviderType.OleDb ? $"Provider={provider};Data Source={fileName}" : $"Driver={{{provider}}};DBQ={fileName}"; @@ -486,7 +486,7 @@ namespace System.Data.Jet return File.Exists(fileName); } - public static DataAccessType GetDataAccessType(string connectionString) + public static DataAccessProviderType GetDataAccessProviderType(string connectionString) { var isOleDb = Regex.IsMatch(connectionString, @"Provider\s*=\s*\w+", RegexOptions.IgnoreCase); var isOdbc = Regex.IsMatch(connectionString, @"Driver\s*=\s*\{?\w+\}?", RegexOptions.IgnoreCase); @@ -498,11 +498,11 @@ namespace System.Data.Jet throw new ArgumentException("The connection string appears to be neither ODBC nor OLE DB compliant.", nameof(connectionString)); return isOleDb - ? DataAccessType.OleDb - : DataAccessType.Odbc; + ? DataAccessProviderType.OleDb + : DataAccessProviderType.Odbc; } - public static DataAccessType GetDataAccessType(DbProviderFactory providerFactory) + public static DataAccessProviderType GetDataAccessProviderType(DbProviderFactory providerFactory) { var isOleDb = providerFactory .GetType() @@ -529,8 +529,8 @@ namespace System.Data.Jet throw new ArgumentException($"The parameter is neither of type OdbcFactory nor OleDbFactory.", nameof(providerFactory)); return isOleDb - ? DataAccessType.OleDb - : DataAccessType.Odbc; + ? DataAccessProviderType.OleDb + : DataAccessProviderType.Odbc; } } } \ No newline at end of file diff --git a/test/EFCore.Jet.FunctionalTests/EFCore.Jet.FunctionalTests.csproj b/test/EFCore.Jet.FunctionalTests/EFCore.Jet.FunctionalTests.csproj index 8558a8f..f5c899a 100644 --- a/test/EFCore.Jet.FunctionalTests/EFCore.Jet.FunctionalTests.csproj +++ b/test/EFCore.Jet.FunctionalTests/EFCore.Jet.FunctionalTests.csproj @@ -63,6 +63,7 @@ PreserveNewest + @@ -82,4 +83,12 @@ + + + + + + + + diff --git a/test/EFCore.Jet.FunctionalTests/JetDatabaseCreatorTest.cs b/test/EFCore.Jet.FunctionalTests/JetDatabaseCreatorTest.cs index 10e1262..752e36a 100644 --- a/test/EFCore.Jet.FunctionalTests/JetDatabaseCreatorTest.cs +++ b/test/EFCore.Jet.FunctionalTests/JetDatabaseCreatorTest.cs @@ -517,8 +517,8 @@ namespace EntityFrameworkCore.Jet.FunctionalTests [ConditionalFact] public void Throws_when_no_initial_catalog() { - var dataAccessType = JetConnection.GetDataAccessProviderType(TestEnvironment.DefaultConnection); - var dataAccessProviderFactory = JetFactory.Instance.GetDataAccessProviderFactory(dataAccessType); + var dataAccessProviderType = JetConnection.GetDataAccessProviderType(TestEnvironment.DefaultConnection); + var dataAccessProviderFactory = JetFactory.Instance.GetDataAccessProviderFactory(dataAccessProviderType); var connectionStringBuilder = dataAccessProviderFactory.CreateConnectionStringBuilder(); connectionStringBuilder.ConnectionString = TestEnvironment.DefaultConnection; connectionStringBuilder.Remove("Initial Catalog"); diff --git a/test/EFCore.Jet.FunctionalTests/Query/NavigationTest.cs b/test/EFCore.Jet.FunctionalTests/Query/NavigationTest.cs index 7f1a48b..12bd478 100644 --- a/test/EFCore.Jet.FunctionalTests/Query/NavigationTest.cs +++ b/test/EFCore.Jet.FunctionalTests/Query/NavigationTest.cs @@ -105,14 +105,14 @@ namespace EntityFrameworkCore.Jet.FunctionalTests.Query .AddEntityFrameworkJet() .BuildServiceProvider(validateScopes: true); - var dataAccessType = JetConnection.GetDataAccessType(TestEnvironment.DefaultConnection); - var dataAccessProviderFactory = JetFactory.Instance.CreateDataAccessProviderFactory(dataAccessType); + var dataAccessProviderType = JetConnection.GetDataAccessProviderType(TestEnvironment.DefaultConnection); + var dataAccessProviderFactory = JetFactory.Instance.GetDataAccessProviderFactory(dataAccessProviderType); var connectionStringBuilder = dataAccessProviderFactory.CreateConnectionStringBuilder(); connectionStringBuilder.ConnectionString = TestEnvironment.DefaultConnection; connectionStringBuilder.SetDataSource("StateManagerBug.accdb"); _options = new DbContextOptionsBuilder() - .UseJet(connectionStringBuilder.ConnectionString, JetConfiguration.DefaultProviderFactory, b => b.ApplyConfiguration()) + .UseJet(connectionStringBuilder.ConnectionString, TestEnvironment.DataAccessProviderFactory, b => b.ApplyConfiguration()) .UseInternalServiceProvider(serviceProvider) .Options; } diff --git a/test/EFCore.Jet.FunctionalTests/TestUtilities/AssertSqlHelper.cs b/test/EFCore.Jet.FunctionalTests/TestUtilities/AssertSqlHelper.cs new file mode 100644 index 0000000..8d9bbfa --- /dev/null +++ b/test/EFCore.Jet.FunctionalTests/TestUtilities/AssertSqlHelper.cs @@ -0,0 +1,22 @@ +using System.Data.Jet; + +namespace EntityFrameworkCore.Jet.FunctionalTests.TestUtilities +{ + public static class AssertSqlHelper + { + static AssertSqlHelper() + { + DataAccessProviderType = TestEnvironment.DataAccessProviderType; + } + + public static DataAccessProviderType DataAccessProviderType { get; set; } + + public static string Parameter(string name) + => Parameter(name, DataAccessProviderType); + + public static string Parameter(string name, DataAccessProviderType dataAccessProviderType) + => dataAccessProviderType == DataAccessProviderType.Odbc + ? "?" + : name; + } +} \ No newline at end of file diff --git a/test/EFCore.Jet.FunctionalTests/TestUtilities/TestEnvironment.cs b/test/EFCore.Jet.FunctionalTests/TestUtilities/TestEnvironment.cs index 4ba3a60..2b0c846 100644 --- a/test/EFCore.Jet.FunctionalTests/TestUtilities/TestEnvironment.cs +++ b/test/EFCore.Jet.FunctionalTests/TestUtilities/TestEnvironment.cs @@ -25,8 +25,8 @@ namespace EntityFrameworkCore.Jet.FunctionalTests.TestUtilities { get { - var dataAccessType = JetConnection.GetDataAccessType(DefaultConnection); - var dataAccessProviderFactory = JetFactory.Instance.GetDataAccessProviderFactory(dataAccessType); + var dataAccessProviderType = JetConnection.GetDataAccessProviderType(DefaultConnection); + var dataAccessProviderFactory = JetFactory.Instance.GetDataAccessProviderFactory(dataAccessProviderType); var connectionStringBuilder = dataAccessProviderFactory.CreateConnectionStringBuilder(); connectionStringBuilder.ConnectionString = DefaultConnection; @@ -34,8 +34,8 @@ namespace EntityFrameworkCore.Jet.FunctionalTests.TestUtilities } } - public static DataAccessProvider DataAccessProvider { get; } = JetConnection.GetDataAccessType(DefaultConnection); - public static DbProviderFactory DataAccessProviderFactory { get; } = JetFactory.Instance.GetDataAccessProviderFactory(JetConnection.GetDataAccessType(DefaultConnection)); + public static DataAccessProviderType DataAccessProviderType { get; } = JetConnection.GetDataAccessProviderType(DefaultConnection); + public static DbProviderFactory DataAccessProviderFactory { get; } = JetFactory.Instance.GetDataAccessProviderFactory(JetConnection.GetDataAccessProviderType(DefaultConnection)); public static bool IsLocalDb { get; } = true; diff --git a/test/System.Data.Jet.Test/ConnectionPoolingTest.cs b/test/System.Data.Jet.Test/ConnectionPoolingTest.cs index b81be9f..39fd5b7 100644 --- a/test/System.Data.Jet.Test/ConnectionPoolingTest.cs +++ b/test/System.Data.Jet.Test/ConnectionPoolingTest.cs @@ -256,8 +256,8 @@ namespace System.Data.Jet.Test { var connectionString = JetConnection.GetConnectionString(StoreName, Helpers.DataAccessProviderFactory); - var dataAccessType = JetConnection.GetDataAccessProviderType(connectionString); - var dataAccessProviderFactory = JetFactory.Instance.GetDataAccessProviderFactory(dataAccessType); + var dataAccessProviderType = JetConnection.GetDataAccessProviderType(connectionString); + var dataAccessProviderFactory = JetFactory.Instance.GetDataAccessProviderFactory(dataAccessProviderType); var connectionStringBuilder = dataAccessProviderFactory.CreateConnectionStringBuilder(); connectionStringBuilder.ConnectionString = connectionString; @@ -271,8 +271,8 @@ namespace System.Data.Jet.Test { var connectionString = JetConnection.GetConnectionString(StoreName, Helpers.DataAccessProviderFactory); - var dataAccessType = JetConnection.GetDataAccessProviderType(connectionString); - var dataAccessProviderFactory = JetFactory.Instance.GetDataAccessProviderFactory(dataAccessType); + var dataAccessProviderType = JetConnection.GetDataAccessProviderType(connectionString); + var dataAccessProviderFactory = JetFactory.Instance.GetDataAccessProviderFactory(dataAccessProviderType); var connectionStringBuilder = dataAccessProviderFactory.CreateConnectionStringBuilder(); connectionStringBuilder.ConnectionString = connectionString;