【问题标题】:Different database context for same EF model (database)?相同 EF 模型(数据库)的不同数据库上下文?
【发布时间】:2018-10-30 11:06:14
【问题描述】:

是否可以为同一个 EF 模型(数据库)添加另一个数据库上下文?我有一种情况,数据库上下文必须根据登录的用户类型而改变。

【问题讨论】:

  • 是的。但是,如果这是 Code-First,您当然可以只在其中一个上启用迁移或数据库初始化。您甚至可以拥有一个 master DbContext,其中包含您仅用于迁移的所有实体..

标签: asp.net-mvc entity-framework model-view-controller


【解决方案1】:

简而言之 - 是的。底层 MODEL 只是数据库表的类表示,因此这里的技巧是使用 Entity Framework 提供的不同数据库驱动程序来建立连接。

例如: 在一个类中实现一个存储库模式,并将其命名为 MySqlContext,该类继承自 DbContext,这将具有 OnConfiguring 方法:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        using (var secretsClient = new InsightSecrets())
        {
            var connectionInfo = // here you add your own depending on environment and project
            string connectionString = connectionInfo.ConnectionString;

            optionsBuilder.UseMySql(connectionString);
        }
    }

在上面的这种情况下,optionsBuilder 实例可以创建一个 MySql 或 Postgress 引用——而这个存储库将在你的代码中通过在类构造函数中执行类似这样的操作而在更高的位置被实例化,其中将使用这个上下文:

var ctx = new MySqlContext();

在此示例中名为 MySqlContext 的存储库可以已经提供 MySql 或 Postgres,但没有什么能阻止您实现另一个存储库,该存储库根据关联的数据库驱动程序提供不同的数据库上下文。

【讨论】:

    【解决方案2】:

    您想要一个不同的DbContext 类还是只是一个不同的数据库? DbContext 类是数据库和您的实体(EF 模型)之间的桥梁。该桥可用于从/向不同数据库传输数据。为同一个 EF 模型创建不同的 DbContext 类对我来说没有多大意义;除非我错过了什么......

    但你可以两者兼得。如果您正在寻找与数据库的另一个连接,那么 这将是您的DbContext 课程,您的“桥梁”:

    public class TestContext : DbContext
    {
        public DbSet<Foo> Foos { get; set; }
        public DbSet<AnotherFoo> AFoos { get; set; }
    
        public TestContext() : this("TestDB1") { }
    
        public TestContext(string databaseName)
            : base(databaseName)
        {
            Configuration.LazyLoadingEnabled = true;
        }
    }
    

    DbContext 与在基本构造函数中提供数据库名称的数据库建立连接。因此,您可以通过构造函数控制它连接的数据库。

    当然,数据库的连接字符串必须在.config 文件中声明。例如:

    <connectionStrings>
      <add name="TestDBContext1" connectionString="Data Source=.\SQLEXPRESS; Initial Catalog=TestDB1; persist security info=True; user id=sa; password=saexpress;" providerName="System.Data.SqlClient" />
      <add name="TestDBContext2" connectionString="Data Source=.\SQLEXPRESS; Initial Catalog=TestDB2; persist security info=True; user id=sa; password=saexpress;" providerName="System.Data.SqlClient" />
    </connectionStrings>
    

    不过,我的建议是不要直接使用构造函数,而是使用工厂设计模式来创建DbContext 的适当实例。

    【讨论】:

      【解决方案3】:

      在实体框架中,DbContext 类表示某种数据库布局。 DbContext中的DbSet&lt;TEntity&gt;代表这个数据库中的表; TEntity 的非虚属性表示表的列,TEntity 的虚属性表示表之间的关系(一对多、多对多……)

      如果您想要一个不同的数据库实例,具有完全相同的布局,只需在构造函数中创建一个不同的“NameOrConnectionString”作为输入参数的数据库实例就足够了。

      如果你想要一个非常相似的数据库,你想重用其他数据库中的一些表和关系,你应该创建一个不同的DbContext类;毕竟:DbContext 类代表你的数据库布局,不同的布局意味着不同的 DbContext。

      可能在第二个DbContext 中,您还需要与默认实体框架值不同的关系、不同的字符串长度、不同的表名(等等)。在这种情况下,最好在 DbContext.OnModelCreating 中使用 Fluent API,而不是在实体类中使用属​​性。这样,您可以重用相同的实体类,同时赋予它们不同的列名、字符串长度、小数精度等。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-10
        • 2015-12-07
        • 1970-01-01
        • 2012-04-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多