将 DbContext 拆分为具有重叠 DbSet 的多个上下文

Splitting DbContext into multiple contexts with overlapping DbSets

我有一个 DbContext,目前包含 +80 个实体,只完成了 4 个主要模块,但还有 3 个要完成,而且它们相当大,所以很容易达到 150 个。我认为现在是划分上下文的最佳时机。每个模块都使用它自己的实体并将获得它自己的上下文,但是所有模块都使用一组实体,所以这里有一个问题:

我是否应该拥有一个包含所有重叠实体的 MainContext,然后:

我是否应该将重叠的实体放在所有上下文中,但是

我应该留在一个上下文中吗?

还有其他建议吗?

如果您需要使用跨越多个 DbContext 的事务,您将遇到问题。无论是否所有的 DbContext 都连接到同一个数据库,它都会被提升为分布式事务。这让事情变得很慢。

您还将失去工作单元的好处,因为 DbContext 将独立跟踪它们的模型。

您仍然可以分离模型并复制共享模型。这不会导致不同的 DbContext 中断关系或死锁,超过两个人 运行 您的软件同时存在两个副本。

但是,为了使事情易于管理,您可以留在一个 DbContext 中,但隐藏每个模块中不需要的模型。

取下面的DbContext-

public class MyContext : DbContext
{
    public DbSet<Person> People { get; set; }
    public DbSet<Vehicle> Cars { get; set; }
    public DbSet<Trip> Trips { get; set; }
    public DbSet<Company> Employers { get; set; }
    public DbSet<Employee> Employees { get; set; }
}

如果你想做一个驾驶模块,你可能只用People, Cars, & Trips。如果您想要一个薪资模块,您可能只使用公司、员工和人员。所以你需要以下接口:

public interface IDrivingContext
{
    DbSet<Person> People { get; }
    DbSet<Vehicle> Cars { get; }
    DbSet<Trip> Trips { get; }
}

public interface IPayrollContext
{
    DbSet<Person> People { get; }
    DbSet<Company> Employers { get; }
    DbSet<Employee> Employees { get; }
}

然后您更改上下文以实现两个接口:

public class MyContext : DbContext, IDrivingContext, IPayrollContext
{
    public DbSet<Person> People { get; set; }
    public DbSet<Vehicle> Cars { get; set; }
    public DbSet<Trip> Trips { get; set; }
    public DbSet<Company> Employers { get; set; }
    public DbSet<Employee> { get; set; }
}

并且当您使用 DbContext 时,只需将变量键入 IDrivingContextIPayrollContext,具体取决于您在哪个模块中编码:

using (IDrivingContext db = new MyDbContext())
{
     // ...
}

using (IPayrollContext db = new MyDbContext())
{
    // ...
}

我认为拆分上下文是个更好的主意。它使您有可能拥有更轻的上下文和更轻的上下文构建时间。此外,如果您对模块进行了更改,那么它不会影响整个数据库,例如您可以只部署应用程序的一部分。在不同的上下文中保持对象之间的关系是困难的。您可以在业务层处理此问题并将 Id 存储在数据库中。如果您不能以某种方式分离模型,那么我想您需要将它们放在一起。业务层是处理业务逻辑的地方,在那里你可以停止删除仍然链接的实体。然后数据库将处理数据库逻辑,例如:类型、大小、身份……我自己正在使用拆分上下文进行实验。从这里开始: 但是我的要复杂得多,并且还有重叠的实体,例如用户无处不在(创建者,修改者,...)