From 7a6e90b4f153d26ec10bd08ab0def0ee8cefe69d Mon Sep 17 00:00:00 2001 From: Laurents Meyer Date: Sat, 28 Nov 2020 12:35:55 +0100 Subject: [PATCH 1/3] Rename solution. --- EntityFrameworkCore.Jet.sln => EFCore.Jet.sln | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) rename EntityFrameworkCore.Jet.sln => EFCore.Jet.sln (81%) diff --git a/EntityFrameworkCore.Jet.sln b/EFCore.Jet.sln similarity index 81% rename from EntityFrameworkCore.Jet.sln rename to EFCore.Jet.sln index 4af6c7a2..4f2207d5 100644 --- a/EntityFrameworkCore.Jet.sln +++ b/EFCore.Jet.sln @@ -51,6 +51,10 @@ ProjectSection(SolutionItems) = preProject tools\Resources.tt = tools\Resources.tt EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EFCore.Jet.Odbc", "src\EFCore.Jet.Odbc\EFCore.Jet.Odbc.csproj", "{1E0729DA-B861-46EA-B1F1-3AE20EA1E00A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EFCore.Jet.OleDb", "src\EFCore.Jet.OleDb\EFCore.Jet.OleDb.csproj", "{FFC89A2D-F68F-47E3-BA00-47E9C0BEDB71}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -145,6 +149,30 @@ Global {5CD8B47D-E32C-480A-8331-55549EC8E12E}.Release|x64.Build.0 = Release|x64 {5CD8B47D-E32C-480A-8331-55549EC8E12E}.Release|x86.ActiveCfg = Release|x86 {5CD8B47D-E32C-480A-8331-55549EC8E12E}.Release|x86.Build.0 = Release|x86 + {1E0729DA-B861-46EA-B1F1-3AE20EA1E00A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1E0729DA-B861-46EA-B1F1-3AE20EA1E00A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1E0729DA-B861-46EA-B1F1-3AE20EA1E00A}.Debug|x64.ActiveCfg = Debug|Any CPU + {1E0729DA-B861-46EA-B1F1-3AE20EA1E00A}.Debug|x64.Build.0 = Debug|Any CPU + {1E0729DA-B861-46EA-B1F1-3AE20EA1E00A}.Debug|x86.ActiveCfg = Debug|Any CPU + {1E0729DA-B861-46EA-B1F1-3AE20EA1E00A}.Debug|x86.Build.0 = Debug|Any CPU + {1E0729DA-B861-46EA-B1F1-3AE20EA1E00A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1E0729DA-B861-46EA-B1F1-3AE20EA1E00A}.Release|Any CPU.Build.0 = Release|Any CPU + {1E0729DA-B861-46EA-B1F1-3AE20EA1E00A}.Release|x64.ActiveCfg = Release|Any CPU + {1E0729DA-B861-46EA-B1F1-3AE20EA1E00A}.Release|x64.Build.0 = Release|Any CPU + {1E0729DA-B861-46EA-B1F1-3AE20EA1E00A}.Release|x86.ActiveCfg = Release|Any CPU + {1E0729DA-B861-46EA-B1F1-3AE20EA1E00A}.Release|x86.Build.0 = Release|Any CPU + {FFC89A2D-F68F-47E3-BA00-47E9C0BEDB71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FFC89A2D-F68F-47E3-BA00-47E9C0BEDB71}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FFC89A2D-F68F-47E3-BA00-47E9C0BEDB71}.Debug|x64.ActiveCfg = Debug|Any CPU + {FFC89A2D-F68F-47E3-BA00-47E9C0BEDB71}.Debug|x64.Build.0 = Debug|Any CPU + {FFC89A2D-F68F-47E3-BA00-47E9C0BEDB71}.Debug|x86.ActiveCfg = Debug|Any CPU + {FFC89A2D-F68F-47E3-BA00-47E9C0BEDB71}.Debug|x86.Build.0 = Debug|Any CPU + {FFC89A2D-F68F-47E3-BA00-47E9C0BEDB71}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FFC89A2D-F68F-47E3-BA00-47E9C0BEDB71}.Release|Any CPU.Build.0 = Release|Any CPU + {FFC89A2D-F68F-47E3-BA00-47E9C0BEDB71}.Release|x64.ActiveCfg = Release|Any CPU + {FFC89A2D-F68F-47E3-BA00-47E9C0BEDB71}.Release|x64.Build.0 = Release|Any CPU + {FFC89A2D-F68F-47E3-BA00-47E9C0BEDB71}.Release|x86.ActiveCfg = Release|Any CPU + {FFC89A2D-F68F-47E3-BA00-47E9C0BEDB71}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -157,6 +185,8 @@ Global {3C88D49A-7EF2-42BA-A8D7-9DF7D358FD24} = {6A8DE399-1804-4113-A408-F23B7F5C9CAC} {770A076B-A448-499C-BB86-A37994C04523} = {6A8DE399-1804-4113-A408-F23B7F5C9CAC} {5CD8B47D-E32C-480A-8331-55549EC8E12E} = {6A8DE399-1804-4113-A408-F23B7F5C9CAC} + {1E0729DA-B861-46EA-B1F1-3AE20EA1E00A} = {F68095EE-6CD1-43A2-B498-6CA72CE2A0CB} + {FFC89A2D-F68F-47E3-BA00-47E9C0BEDB71} = {F68095EE-6CD1-43A2-B498-6CA72CE2A0CB} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {9359773D-6399-447E-9814-6CB41C2FB664} From 4158e517fb7d1495b822eeea21ed1b172dd8a154 Mon Sep 17 00:00:00 2001 From: Laurents Meyer Date: Sat, 28 Nov 2020 12:36:04 +0100 Subject: [PATCH 2/3] Add ODBC and OLE DB specific projects/packages. --- Directory.Build.props | 3 +- src/Directory.Build.props | 1 + src/EFCore.Jet.Odbc/EFCore.Jet.Odbc.csproj | 23 ++++ ...etOdbcDbContextOptionsBuilderExtensions.cs | 103 ++++++++++++++++++ src/EFCore.Jet.OleDb/EFCore.Jet.OleDb.csproj | 23 ++++ .../JetDbContextOptionsBuilderExtensions.cs | 103 ++++++++++++++++++ src/EFCore.Jet/EFCore.Jet.csproj | 1 + .../JetDbContextOptionsBuilderExtensions.cs | 14 ++- src/System.Data.Jet/JetFactory.cs | 26 ++++- 9 files changed, 289 insertions(+), 8 deletions(-) create mode 100644 src/EFCore.Jet.Odbc/EFCore.Jet.Odbc.csproj create mode 100644 src/EFCore.Jet.Odbc/Extensions/JetOdbcDbContextOptionsBuilderExtensions.cs create mode 100644 src/EFCore.Jet.OleDb/EFCore.Jet.OleDb.csproj create mode 100644 src/EFCore.Jet.OleDb/Extensions/JetDbContextOptionsBuilderExtensions.cs diff --git a/Directory.Build.props b/Directory.Build.props index 2d35a8b6..a17cc7bb 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,7 +4,6 @@ EntityFrameworkCore.Jet - Jet (Microsoft Access mdb or accdb files) provider for Entity Framework Core (EFCore) Laurents Meyer, Bubi Bubi Copyright © 2017-2020 Bubi @@ -13,7 +12,7 @@ portable False - Entity Framework Core Jet;Entity Framework Core Access;Entity Framework Core MS Access;entity-framework-core-jet;entity-framework-core-access;entity-framework-core-msaccess;EF Jet;EF Access;EF MS Access;Data;O/RM;EntityFramework;EntityFrameworkCore;EFCore;Jet;Access;MS Access + Entity Framework Core Jet;Entity Framework Core Access;Entity Framework Core MS Access;entity-framework-core-jet;entity-framework-core-access;entity-framework-core-msaccess;EF Jet;EF Access;EF MS Access;Data;O/RM;EntityFramework;EntityFrameworkCore;EFCore;Jet;Access;MS Access;ACE Apache-2.0 https://github.com/bubibubi/EntityFrameworkCore.Jet diff --git a/src/Directory.Build.props b/src/Directory.Build.props index e7474aad..7b511be2 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -31,5 +31,6 @@ true true snupkg + 3.6 diff --git a/src/EFCore.Jet.Odbc/EFCore.Jet.Odbc.csproj b/src/EFCore.Jet.Odbc/EFCore.Jet.Odbc.csproj new file mode 100644 index 00000000..ab39b4a1 --- /dev/null +++ b/src/EFCore.Jet.Odbc/EFCore.Jet.Odbc.csproj @@ -0,0 +1,23 @@ + + + + Explicit ODBC support for Jet/ACE database provider for Entity Framework Core (Microsoft Access MDB/ACCDB files). + $(DefaultNetStandardTargetFramework) + EntityFrameworkCore.Jet.Odbc + EntityFrameworkCore.Jet + $(PackageTags);ODBC;System.Data.Odbc + + + + + + + + + + + + + + + diff --git a/src/EFCore.Jet.Odbc/Extensions/JetOdbcDbContextOptionsBuilderExtensions.cs b/src/EFCore.Jet.Odbc/Extensions/JetOdbcDbContextOptionsBuilderExtensions.cs new file mode 100644 index 00000000..a526faf9 --- /dev/null +++ b/src/EFCore.Jet.Odbc/Extensions/JetOdbcDbContextOptionsBuilderExtensions.cs @@ -0,0 +1,103 @@ +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Data.Jet; +using System.Data.Odbc; +using EntityFrameworkCore.Jet.Infrastructure; +using JetBrains.Annotations; +using EntityFrameworkCore.Jet.Utilities; + +// ReSharper disable once CheckNamespace +namespace Microsoft.EntityFrameworkCore +{ + /// + /// Jet specific ODBC extension methods for . + /// + public static class JetOdbcDbContextOptionsBuilderExtensions + { + #region Connection String + + /// + /// Configures the context to connect to a Microsoft Jet database using ODBC. + /// + /// The builder being used to configure the context. + /// The file name or ODBC connection string of the database to connect + /// to. In case the connection string does not specify an Access driver (ODBC), the highest version of all + /// compatible installed ones is being used. + /// An optional action to allow additional Jet specific configuration. + /// The options builder so that further configuration can be chained. + public static DbContextOptionsBuilder UseJetOdbc( + [NotNull] this DbContextOptionsBuilder optionsBuilder, + [NotNull] string fileNameOrConnectionString, + [CanBeNull] Action jetOptionsAction = null) + where TContext : DbContext + => optionsBuilder.UseJet(fileNameOrConnectionString, DataAccessProviderType.Odbc, jetOptionsAction); + + /// + /// Configures the context to connect to a Microsoft Jet database using ODBC. + /// + /// The builder being used to configure the context. + /// The file name or ODBC connection string of the database to connect + /// to. In case the connection string does not specify an Access driver (ODBC), the highest version of all + /// compatible installed ones is being used. + /// An optional action to allow additional Jet specific configuration. + /// The options builder so that further configuration can be chained. + public static DbContextOptionsBuilder UseJetOdbc( + [NotNull] this DbContextOptionsBuilder optionsBuilder, + [NotNull] string fileNameOrConnectionString, + [CanBeNull] Action jetOptionsAction = null) + => optionsBuilder.UseJet(fileNameOrConnectionString, DataAccessProviderType.Odbc, jetOptionsAction); + + #endregion + + #region Connection + + /// + /// Configures the context to connect to a Microsoft Jet database using ODBC. + /// + /// The type of context to be configured. + /// The builder being used to configure the context. + /// + /// An existing to be used to connect to the database. If the connection is in + /// the open state then EF will not open or close the connection. If the connection is in the closed state + /// then EF will open and close the connection as needed. + /// + /// An optional action to allow additional Jet specific configuration. + /// The options builder so that further configuration can be chained. + public static DbContextOptionsBuilder UseJetOdbc( + [NotNull] this DbContextOptionsBuilder optionsBuilder, + [NotNull] OdbcConnection connection, + [CanBeNull] Action jetOptionsAction = null) + where TContext : DbContext + { + Check.NotNull(optionsBuilder, nameof(optionsBuilder)); + Check.NotNull(connection, nameof(connection)); + + return optionsBuilder.UseJet(connection, jetOptionsAction); + } + + /// + /// Configures the context to connect to a Microsoft Jet database using ODBC. + /// + /// The builder being used to configure the context. + /// + /// An existing to be used to connect to the database. If the connection is in + /// the open state then EF will not open or close the connection. If the connection is in the closed state + /// then EF will open and close the connection as needed. + /// + /// An optional action to allow additional Jet specific configuration. + /// The options builder so that further configuration can be chained. + public static DbContextOptionsBuilder UseJetOdbc( + [NotNull] this DbContextOptionsBuilder optionsBuilder, + [NotNull] OdbcConnection connection, + [CanBeNull] Action jetOptionsAction = null) + { + Check.NotNull(optionsBuilder, nameof(optionsBuilder)); + Check.NotNull(connection, nameof(connection)); + + return optionsBuilder.UseJet(connection, jetOptionsAction); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/EFCore.Jet.OleDb/EFCore.Jet.OleDb.csproj b/src/EFCore.Jet.OleDb/EFCore.Jet.OleDb.csproj new file mode 100644 index 00000000..7f6ea449 --- /dev/null +++ b/src/EFCore.Jet.OleDb/EFCore.Jet.OleDb.csproj @@ -0,0 +1,23 @@ + + + + Explicit OLE DB support for Jet/ACE database provider for Entity Framework Core (Microsoft Access MDB/ACCDB files). + $(DefaultNetStandardTargetFramework) + EntityFrameworkCore.Jet.OleDb + EntityFrameworkCore.Jet + $(PackageTags);OLE DB;OLEDB;System.Data.OleDb + + + + + + + + + + + + + + + diff --git a/src/EFCore.Jet.OleDb/Extensions/JetDbContextOptionsBuilderExtensions.cs b/src/EFCore.Jet.OleDb/Extensions/JetDbContextOptionsBuilderExtensions.cs new file mode 100644 index 00000000..9fb587e2 --- /dev/null +++ b/src/EFCore.Jet.OleDb/Extensions/JetDbContextOptionsBuilderExtensions.cs @@ -0,0 +1,103 @@ +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Data.Jet; +using System.Data.OleDb; +using EntityFrameworkCore.Jet.Infrastructure; +using JetBrains.Annotations; +using EntityFrameworkCore.Jet.Utilities; + +// ReSharper disable once CheckNamespace +namespace Microsoft.EntityFrameworkCore +{ + /// + /// Jet specific OLE DB extension methods for . + /// + public static class JetOleDbDbContextOptionsBuilderExtensions + { + #region Connection String + + /// + /// Configures the context to connect to a Microsoft Jet database using OLE DB. + /// + /// The builder being used to configure the context. + /// The file name or OLE DB connection string of the database to connect + /// to. In case the connection string does not specify an Jet/ACE provider (OLE DB), the highest version of all + /// compatible installed ones is being used. + /// An optional action to allow additional Jet specific configuration. + /// The options builder so that further configuration can be chained. + public static DbContextOptionsBuilder UseJetOleDb( + [NotNull] this DbContextOptionsBuilder optionsBuilder, + [NotNull] string fileNameOrConnectionString, + [CanBeNull] Action jetOptionsAction = null) + where TContext : DbContext + => optionsBuilder.UseJet(fileNameOrConnectionString, DataAccessProviderType.OleDb, jetOptionsAction); + + /// + /// Configures the context to connect to a Microsoft Jet database using OLE DB. + /// + /// The builder being used to configure the context. + /// The file name or OLE DB connection string of the database to connect + /// to. In case the connection string does not specify an Jet/ACE provider (OLE DB), the highest version of all + /// compatible installed ones is being used. + /// An optional action to allow additional Jet specific configuration. + /// The options builder so that further configuration can be chained. + public static DbContextOptionsBuilder UseJetOleDb( + [NotNull] this DbContextOptionsBuilder optionsBuilder, + [NotNull] string fileNameOrConnectionString, + [CanBeNull] Action jetOptionsAction = null) + => optionsBuilder.UseJet(fileNameOrConnectionString, DataAccessProviderType.OleDb, jetOptionsAction); + + #endregion + + #region Connection + + /// + /// Configures the context to connect to a Microsoft Jet database using OLE DB. + /// + /// The type of context to be configured. + /// The builder being used to configure the context. + /// + /// An existing to be used to connect to the database. If the connection is in + /// the open state then EF will not open or close the connection. If the connection is in the closed state + /// then EF will open and close the connection as needed. + /// + /// An optional action to allow additional Jet specific configuration. + /// The options builder so that further configuration can be chained. + public static DbContextOptionsBuilder UseJetOleDb( + [NotNull] this DbContextOptionsBuilder optionsBuilder, + [NotNull] OleDbConnection connection, + [CanBeNull] Action jetOptionsAction = null) + where TContext : DbContext + { + Check.NotNull(optionsBuilder, nameof(optionsBuilder)); + Check.NotNull(connection, nameof(connection)); + + return optionsBuilder.UseJet(connection, jetOptionsAction); + } + + /// + /// Configures the context to connect to a Microsoft Jet database using OLE DB. + /// + /// The builder being used to configure the context. + /// + /// An existing to be used to connect to the database. If the connection is in + /// the open state then EF will not open or close the connection. If the connection is in the closed state + /// then EF will open and close the connection as needed. + /// + /// An optional action to allow additional Jet specific configuration. + /// The options builder so that further configuration can be chained. + public static DbContextOptionsBuilder UseJetOleDb( + [NotNull] this DbContextOptionsBuilder optionsBuilder, + [NotNull] OleDbConnection connection, + [CanBeNull] Action jetOptionsAction = null) + { + Check.NotNull(optionsBuilder, nameof(optionsBuilder)); + Check.NotNull(connection, nameof(connection)); + + return optionsBuilder.UseJet(connection, jetOptionsAction); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/EFCore.Jet/EFCore.Jet.csproj b/src/EFCore.Jet/EFCore.Jet.csproj index c97022fe..9e137938 100644 --- a/src/EFCore.Jet/EFCore.Jet.csproj +++ b/src/EFCore.Jet/EFCore.Jet.csproj @@ -1,6 +1,7 @@  + Jet/ACE database provider for Entity Framework Core (Microsoft Access MDB/ACCDB files). $(DefaultNetStandardTargetFramework);netcoreapp2.1;net461 EntityFrameworkCore.Jet EntityFrameworkCore.Jet diff --git a/src/EFCore.Jet/Extensions/JetDbContextOptionsBuilderExtensions.cs b/src/EFCore.Jet/Extensions/JetDbContextOptionsBuilderExtensions.cs index afd9fc03..d9ee039c 100644 --- a/src/EFCore.Jet/Extensions/JetDbContextOptionsBuilderExtensions.cs +++ b/src/EFCore.Jet/Extensions/JetDbContextOptionsBuilderExtensions.cs @@ -37,7 +37,12 @@ public static DbContextOptionsBuilder UseJet( [NotNull] string fileNameOrConnectionString, [CanBeNull] Action jetOptionsAction = null) where TContext : DbContext - => (DbContextOptionsBuilder) UseJet((DbContextOptionsBuilder) optionsBuilder, fileNameOrConnectionString, jetOptionsAction); + { + Check.NotNull(optionsBuilder, nameof(optionsBuilder)); + Check.NotEmpty(fileNameOrConnectionString, nameof(fileNameOrConnectionString)); + + return (DbContextOptionsBuilder) UseJet((DbContextOptionsBuilder) optionsBuilder, fileNameOrConnectionString, jetOptionsAction); + } /// /// Configures the context to connect to a Microsoft Jet database. @@ -219,8 +224,13 @@ public static DbContextOptionsBuilder UseJet( [NotNull] DbConnection connection, [CanBeNull] Action jetOptionsAction = null) where TContext : DbContext - => (DbContextOptionsBuilder) UseJet( + { + Check.NotNull(optionsBuilder, nameof(optionsBuilder)); + Check.NotNull(connection, nameof(connection)); + + return (DbContextOptionsBuilder) UseJet( (DbContextOptionsBuilder) optionsBuilder, connection, jetOptionsAction); + } // Note: Decision made to use DbConnection not SqlConnection: Issue #772 /// diff --git a/src/System.Data.Jet/JetFactory.cs b/src/System.Data.Jet/JetFactory.cs index 8ab42b22..c9db08e4 100644 --- a/src/System.Data.Jet/JetFactory.cs +++ b/src/System.Data.Jet/JetFactory.cs @@ -8,6 +8,8 @@ namespace System.Data.Jet /// public class JetFactory : DbProviderFactory { + public static readonly Version MinimumRequiredOdbcVersion = new Version(5, 0, 0); + public static readonly Version MinimumRequiredOleDbVersion = new Version(5, 0, 0); public static readonly JetFactory Instance = new JetFactory(null, null); public JetConnection Connection { get; } @@ -117,26 +119,42 @@ public virtual DbProviderFactory GetDataAccessProviderFactory(DataAccessProvider { try { - return (DbProviderFactory) Type.GetType("System.Data.OleDb.OleDbFactory, System.Data.OleDb") + var type = Type.GetType("System.Data.OleDb.OleDbFactory, System.Data.OleDb"); + var version = type.Assembly.GetName().Version; + + if (version < MinimumRequiredOleDbVersion) + { + throw new TypeLoadException($"The referenced version '{version}' of 'System.Data.OleDb' is lower than the minimum required version {MinimumRequiredOleDbVersion}."); + } + + return (DbProviderFactory) type .GetField("Instance", BindingFlags.Static | BindingFlags.Public) .GetValue(null); } catch (Exception e) { - throw new TypeLoadException("To use OLE DB in conjunction with Jet, please reference the \"System.Data.OleDb\" NuGet package.", e); + throw new TypeLoadException("To use OLE DB in conjunction with Jet, please reference the 'System.Data.OleDb' (version >= 5.0.0) NuGet package.", e); } } else { try { - return (DbProviderFactory) Type.GetType("System.Data.Odbc.OdbcFactory, System.Data.Odbc") + var type = Type.GetType("System.Data.Odbc.OdbcFactory, System.Data.Odbc"); + var version = type.Assembly.GetName().Version; + + if (version < MinimumRequiredOdbcVersion) + { + throw new TypeLoadException($"The referenced version '{version}' of 'System.Data.Odbc' is lower than the minimum required version {MinimumRequiredOdbcVersion}."); + } + + return (DbProviderFactory) type .GetField("Instance", BindingFlags.Static | BindingFlags.Public) .GetValue(null); } catch (Exception e) { - throw new TypeLoadException("To use ODBC in conjunction with Jet, please reference the \"System.Data.Odbc\" NuGet package.", e); + throw new TypeLoadException("To use ODBC in conjunction with Jet, please reference the 'System.Data.Odbc' (version >= 5.0.0) NuGet package.", e); } } } From b70b409e1362a164066e95d9f83a012946ea5155 Mon Sep 17 00:00:00 2001 From: Laurents Meyer Date: Sat, 28 Nov 2020 14:40:18 +0100 Subject: [PATCH 3/3] Adjust package tags. --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index a17cc7bb..8e20792b 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -12,7 +12,7 @@ portable False - Entity Framework Core Jet;Entity Framework Core Access;Entity Framework Core MS Access;entity-framework-core-jet;entity-framework-core-access;entity-framework-core-msaccess;EF Jet;EF Access;EF MS Access;Data;O/RM;EntityFramework;EntityFrameworkCore;EFCore;Jet;Access;MS Access;ACE + Entity Framework Core;Entity Framework Core;entity-framework-core;Jet;ACE;Access;MS Access;msaccess;EF;EFCore;EF Core;EntityFrameworkCore Apache-2.0 https://github.com/bubibubi/EntityFrameworkCore.Jet