具有单数据库多上下文的 EF6 Code First 迁移

EF6 Code First Migration with single database multiple context

我正在使用 3 个项目构建 Asp.net MVC5 + EF6 解决方案。 我在我的项目中启用了自动迁移。 下图显示了我的项目结构。

  1. 我有一个主项目和两个子项目。
  2. 我在主项目中有一个BaseContext
  3. 子项目有自己的 context 类 派生自 BaseContext
  4. 以上所有上下文都连接到一个数据库。

型号:

Project2 中的模型

public class Product
{
    [Key]
    public int ProductId {get;set;}
    ...
}

Project3 中的模型

public class Order
{
    [Key]
    public int OrderId {get;set;}

    [ForeignKey("Product")]
    public int ProductId {get;set}

    public virtual Product Product;

    ...
}

来自 Project3 实体 (Order.ProductId) 的 属性 引用来自 Project2 的 属性实体 (Product.ProductId) 作为外键引用。

当我在项目 1 和 2 中 运行 update-database 命令时,一切进展顺利。 但是在项目3中使用运行 update-database命令时报错:

There is already an object named 'Product' in the database.

现在我正在使用update-database -script 命令生成脚本并手动更改脚本。但是当项目增长时,每次更改 sql 脚本就变成了一项艰巨的任务。

我通过添加 modelBuilder.Ignore<Product>() 忽略了 Product 实体,以便在 Project3 中跳过 Product 实体的 table 创建, 但它忽略了整个关系。

我该如何解决这个问题?

你不能这样做。一个上下文 == 一个数据库。当您 运行 针对特定上下文的数据库进行迁移时,它将基于该上下文,并将删除任何不适用的表或尝试删除并重新创建数据库。

您应该将所有实体移动到一个 class 库中,连同包含所有实体的上下文的单个实例。然后,您可以针对 class 库进行迁移,并在您的其他项目中简单地引用。

或者,您可以通过使用现有的数据库方法来做您想做的事。本质上,您完全关闭基上下文的迁移,然后每个子上下文只能包含属于它的实体。但是,届时您将完全负责自己管理数据库。

public class BaseContext : DbContext
{
    public BaseContext()
        : base("ConnectionString")
    {
        Database.SetInitializer<BaseContext>(null);
    }
}