using System; using System.Data.Common; using System.Reflection; namespace EntityFrameworkCore.Jet.Data { /// /// Jet provider factory /// public class JetFactory : DbProviderFactory { public static readonly Version MinimumRequiredOdbcVersion = new Version(6, 0, 0); public static readonly Version MinimumRequiredOleDbVersion = new Version(6, 0, 0); public static readonly JetFactory Instance = new JetFactory(null, null); public JetConnection? Connection { get; } internal DbProviderFactory? InnerFactory { get; } internal JetFactory(JetConnection? connection, DbProviderFactory? innerFactory) { if (innerFactory is JetFactory) throw new ArgumentException("JetProviderFactory cannot use a JetProviderFactory as its underlying provider factory. Supported provider factories are OdbcFactory and OleDbFactory."); Connection = connection; InnerFactory = innerFactory; } /// /// Specifies whether the specific supports the class. /// public override bool CanCreateDataSourceEnumerator => false; /// /// Returns a new instance of the provider's class that implements the class. /// /// /// A new instance of . /// public override DbCommand CreateCommand() => InnerFactory == null ? throw new InvalidOperationException(Messages.CannotCallJetProviderFactoryMethodOnSingletonInstance(nameof(CreateCommand))) : new JetCommand(Connection); /// /// Returns a new instance of the provider's class that implements the class. /// /// /// A new instance of . /// public override DbCommandBuilder CreateCommandBuilder() { if (InnerFactory == null) throw new InvalidOperationException(Messages.CannotCallJetProviderFactoryMethodOnSingletonInstance(nameof(CreateCommandBuilder))); var commandBuilder = InnerFactory.CreateCommandBuilder(); commandBuilder.QuotePrefix = "`"; commandBuilder.QuoteSuffix = "`"; return commandBuilder; } /// /// Returns a new instance of the provider's class that implements the class. /// /// /// A new instance of . /// public override DbConnection CreateConnection() => InnerFactory == null ? new JetConnection() : new JetConnection(InnerFactory); /// /// Returns a new instance of the provider's class that implements the class. /// /// /// A new instance of . /// public override DbConnectionStringBuilder CreateConnectionStringBuilder() => InnerFactory == null ? throw new InvalidOperationException(Messages.CannotCallJetProviderFactoryMethodOnSingletonInstance(nameof(CreateConnectionStringBuilder))) : new JetConnectionStringBuilder(InnerFactory); /// /// Returns a new instance of the provider's class that implements the class. /// /// /// A new instance of . /// public override DbDataAdapter CreateDataAdapter() => InnerFactory == null ? throw new InvalidOperationException(Messages.CannotCallJetProviderFactoryMethodOnSingletonInstance(nameof(CreateDataAdapter))) : InnerFactory.CreateDataAdapter(); /// /// Returns a new instance of the provider's class that implements the class. /// /// /// A new instance of . /// public override DbDataSourceEnumerator? CreateDataSourceEnumerator() => null; /// /// Returns a new instance of the provider's class that implements the class. /// /// /// A new instance of . /// public override DbParameter CreateParameter() => InnerFactory == null ? throw new InvalidOperationException(Messages.CannotCallJetProviderFactoryMethodOnSingletonInstance(nameof(CreateDataAdapter))) : InnerFactory.CreateParameter(); public virtual DbProviderFactory GetDataAccessProviderFactory(DataAccessProviderType dataAccessProviderType) { if (dataAccessProviderType == DataAccessProviderType.OleDb) { try { var type = Type.GetType("System.Data.OleDb.OleDbFactory, System.Data.OleDb"); var assemblyName = type.Assembly.GetName(); var version = assemblyName.Version; if (version < MinimumRequiredOleDbVersion && assemblyName.Name != "System.Data") // For .NET Framework, System.Data.OleDb is just a stub that references the .NET Framework implementation. { 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' (version >= {MinimumRequiredOleDbVersion}) NuGet package.", e); } } else { try { var type = Type.GetType("System.Data.Odbc.OdbcFactory, System.Data.Odbc"); var assemblyName = type.Assembly.GetName(); var version = assemblyName.Version; if (version < MinimumRequiredOdbcVersion && assemblyName.Name != "System.Data") // For .NET Framework, System.Data.Odbc is just a stub that references the .NET Framework implementation. { 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' (version >= {MinimumRequiredOdbcVersion}) NuGet package.", e); } } } } }