在运行时使用EF Core确定正在使用哪个数据库提供程序

本文关键字:数据库 程序 运行时 EF Core | 更新日期: 2023-09-27 18:18:01

NET Core和EF Core系统,我们在系统的不同部分使用了不同的数据库。我需要能够告诉,在运行时,哪个数据库提供程序正在使用,因为有些东西需要考虑到这一点。

在启动过程中,SQL Server有如下设置:

  services.AddDbContext<MyContext>(
    options => options.UseSqlServer(config.GetConnectionString("DefaultConnection"))
  );

  services.AddDbContext<MyContext>(
    options => options.UseSqlite(config.GetConnectionString("DefaultConnection"))
  );

重点是正在使用的数据库的知识包含在系统的某个地方。

在系统中的任意点,我如何确定我正在使用哪个数据库?我能接触到MyContext。里面有什么东西可以揭示这个信息吗?

在运行时使用EF Core确定正在使用哪个数据库提供程序

我在我的项目中使用3个数据库提供商。

  • Npgsql.EntityFrameworkCore.PostgreSQL
  • Microsoft.EntityFrameworkCore.SqlServer
  • Pomelo.EntityFrameworkCore.MySql

没有在我的项目中使用。 。2020年6月17日。我注意到Oracle提供程序有一个extensión方法IsOracle。

  • Oracle。EntityFrameworkCore Oracle。EntityFrameworkCore 3.19.0-beta1

包括在您的客户端项目中,这些引用中的任何一个都可以从Nuget包管理器或CLI中添加。

引用包含以下扩展方法:

Boolean isPostgreSQL = context.Database.IsNpgsql();
Boolean isSqlServer = context.Database.IsSqlServer();
Boolean isMySql = context.Database.IsMySql();
Boolean isOracle= context.Database.IsOracle();

示例1

public static EntityTypeBuilder<TEntity> ToTable<TEntity>(this EntityTypeBuilder<TEntity> builder, string schema, DatabaseFacade database) where  TEntity : class
{
    switch(database)
    {
        case DatabaseFacade db when db.IsMySql():
            builder.ToTable($"{schema}.{typeof(TEntity).Name}");
            break;
        case DatabaseFacade db when db.IsSqlServer() | db.IsNpgsql():
            builder.ToTable(typeof(TEntity).Name, schema);
            break;
        default:
            throw new NotImplementedException("Unknown database provider.");
    }
    return builder;
}
示例2

private static string GetEffectiveConstraintName(string name, DatabaseFacade database)
{
    return database switch
    {
        DatabaseFacade db when db.IsSqlServer() => name,
        DatabaseFacade db when db.IsNpgsql() => name.Length < DataAccessConstants.PostgreSqlIdentifierMaxLength ? name : name.Substring(0, DataAccessConstants.PostgreSqlIdentifierMaxLength),
        DatabaseFacade db when db.IsMySql() => name.Length < DataAccessConstants.MySqlIdentifierMaxLength ? name : name.Substring(0, DataAccessConstants.MySqlIdentifierMaxLength),
        _ => throw new NotImplementedException("Unknown database provider")
    };
}

在系统中任何可以访问MyContext的地方,执行以下操作:

context.Database.GetDbConnection().GetType().Name

例如:SQLite为SqliteConnection, SQL Server为SqlServerConnection,等等。

然而,我不确定你是否需要处理连接之后!

For EF Core 2:

dbContext.Database.ProviderName

我不确定是否有这样做的公共方式,但您可以查看context.Database.DatabaseCreator(您将不得不使用反射来获取DatabaseCreator),但通过查看类型,您可以告诉它是哪种连接。例如,使用SQL,您将获得SqlServerDatabaseCreator。

编辑:是的,看看代码,我不认为有任何其他的方式来告诉除了我上面提到的。UseSqlServer方法不会在任何地方设置任何标志或类似的东西。这只是一个工厂。

您可以从DbContextOptions<T>开始,这是AddDbContext<T>方法的功能,您可以在这里看到。

又被注入到DbContext中。

你也可以尝试在你的服务中请求DbContextOptionsDbContextOptions<MyContext>,然后交互/检查扩展字典。

SqliteOptionsExtension是Sqlite的一个,你可以看到它注册在这里和这里。