【问题标题】:Determine at runtime which db provider is being used, with EF Core使用 EF Core 在运行时确定正在使用哪个数据库提供程序
【发布时间】:2023-03-19 23:15:01
【问题描述】:

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

在启动过程中,SQL Server 有这个:

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

或者这个对于 SQLite:

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

关键是关于正在使用哪个数据库的知识包含在系统中的某个地方。

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

【问题讨论】:

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

标签: c# asp.net entity-framework asp.net-core entity-framework-core


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    例如,SQLite 是SqliteConnection,SQL Server 是SqlServerConnection

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

    【讨论】:

      【解决方案3】:

      您可以从DbContextOptions&lt;T&gt; 开始,这就是AddDbContext&lt;T&gt; 方法的作用,您可以看到here

      然后将其注入 DbContext。

      您也可以尝试在您的服务中请求DbContextOptionsDbContextOptions&lt;MyContext&gt;,然后交互/检查Extensions 字典。

      SqliteOptionsExtension 是 Sqlite 之一,你可以看到它注册了herehere

      【讨论】:

        【解决方案4】:

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

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

        在我的项目中没有使用。 更新。 2020 年 6 月 17 日。我注意到 Oracle Provider 有一个扩展方法 IsOracle。

        在您的客户端项目中,任何这些引用都可以从 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")
            };
        }
        

        【讨论】:

          【解决方案5】:

          对于 EF Core 2:

          dbContext.Database.ProviderName
          

          【讨论】:

            猜你喜欢
            • 2018-12-14
            • 2018-10-12
            • 1970-01-01
            • 2019-10-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-09
            • 1970-01-01
            相关资源
            最近更新 更多