C# 在运行时使用EF Core确定正在使用的db提供程序

C# 在运行时使用EF Core确定正在使用的db提供程序,c#,asp.net,entity-framework,asp.net-core,entity-framework-core,C#,Asp.net,Entity Framework,Asp.net Core,Entity Framework Core,在我们的ASP.NET Core和EF Core系统中,我们为系统的不同部分使用不同的数据库。我需要能够在运行时告诉您正在使用哪个db提供程序,因为有些东西需要考虑到这一点 在启动过程中,SQL Server有以下功能: services.AddDbContext<MyContext>( options => options.UseSqlServer(config.GetConnectionString("DefaultConnection")) ); ser

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

在启动过程中,SQL Server有以下功能:

  services.AddDbContext<MyContext>(
    options => options.UseSqlServer(config.GetConnectionString("DefaultConnection"))
  );
services.AddDbContext(
options=>options.UseSqlServer(config.GetConnectionString(“DefaultConnection”))
);
对于SQLite:

  services.AddDbContext<MyContext>(
    options => options.UseSqlite(config.GetConnectionString("DefaultConnection"))
  );
services.AddDbContext(
options=>options.UseSqlite(config.GetConnectionString(“DefaultConnection”))
);
关键是,使用哪个数据库的知识包含在系统的某个地方


在系统中的某个任意点,如何确定使用的是哪个数据库?我可以访问
MyContext
。有什么东西可以透露这些信息吗?

我不确定是否有公开的方法,但你可以查看context.Database.DatabaseCreator(你必须使用反射才能访问DatabaseCreator),但通过查看类型,你可以知道它是什么类型的连接。例如,使用SQL,您将获得SqlServerDatabaseCreator


编辑:是的,看看代码,除了我上面提到的以外,我不认为还有其他方法可以告诉你。UseSqlServer方法不会在任何地方设置任何标志或类似的内容。它只是一个工厂。

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

context.Database.GetDbConnection().GetType().Name
例如,对于SQLite是
SqliteConnection
,对于SQLServer是
SqlServerConnection
,等等


但是我不确定您是否需要在以后处理连接

您可以从
DbContextOptions
开始,这就是
AddDbContext
方法所做的,您可以看到

这反过来又被注入到DbContext中

您也可以尝试在您的服务中请求
DbContextOptions
DbContextOptions
,然后交互/检查字典


sqliteoptionextension
是Sqlite-one,您可以看到它已注册并已注册

我在project 3数据库提供程序中使用

  • Npgsql.EntityFrameworkCore.PostgreSQL
  • Microsoft.EntityFrameworkCore.SqlServer
  • pomero.EntityFrameworkCore.MySql
在我的项目中没有使用更新。2020年6月17日。我注意到Oracle提供程序有一个extensión方法IsOracle

  • Oracle.EntityFrameworkCore
在您的客户端项目中,可以从Nuget Package manager或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;
}
公共静态EntityTypeBuilder ToTable(此EntityTypeBuilder、字符串模式、DatabaseFacade数据库),其中tenty:class
{
交换机(数据库)
{
case DatabaseFacade db when db.IsMySql():
ToTable($“{schema}.{typeof(tenty.Name}”);
打破
case DatabaseFacade db when db.IsSqlServer()| db.IsNpgsql():
ToTable(typeof(tenty).Name,schema);
打破
违约:
抛出新的NotImplementedException(“未知数据库提供程序”);
}
返回生成器;
}
示例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")
    };
}
私有静态字符串GetEffectiveConstraintName(字符串名称,DatabaseFacade数据库)
{
返回数据库开关
{
DatabaseFacade db当db.IsSqlServer()=>name时,
DatabaseFacade db when db.IsNpgsql()=>name.Lengthname.Length抛出新的NotImplementedException(“未知数据库提供程序”)
};
}
对于EF核心2:

dbContext.Database.ProviderName

在这里定义“动态”。动态如“每次应用程序启动”或动态如“运行时可以随时更改”?@Tseng如在运行时以编程方式确定。两者都是运行时,这就是我问的原因。如果是“每次应用程序启动”的事情,除了连接字符串之外,您还可以将提供程序的类型添加到appsettings.json中。@Tseng这是一个有趣的选择。。。我可以将任意内容放入连接字符串中吗?我应该使用什么格式?