使用重叠的DbSets将DbContext拆分为多个上下文

时间:2015-06-27 09:04:59

标签: c# entity-framework-6 dbcontext

我有一个DbContext,目前只有4个主要模块可容纳+80个实体,但还有3个实体,它们相当大,所以它可以轻松达到150个。我认为这是划分背景的最佳时机。每个模块都使用它自己的实体,并且会获得它自己的上下文,但是所有模块都使用了一组实体,所以这里有mu问题:

我是否应该有一个MainContext,它将包含所有重叠的实体,但是:

  • FK依赖项会发生什么?
  • 嵌套using (var db = new context)会有多少性能问题,因为我需要从每个模块访问主要上下文。

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

  • 映射会发生什么情况,并不是每个上下文都会尝试映射它自己的实体并收到错误?
  • 我应该排除除了一个上下文之外的所有重叠上下文的映射吗?

我应该留在一个背景下吗?

还有其他建议吗?

1 个答案:

答案 0 :(得分:6)

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

您也将失去工作单元的好处,因为DbContexts将独立跟踪他们的模型。

您仍然可以分离模型并复制共享模型。这不会导致各种DbContexts破坏关系或死锁,不止两个人同时运行两个软件副本。

但是,为了保持可管理性,您可以保留一个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> { get; set; }
}

如果你想制作一个驾驶模块,你可能只会使用People,Cars和&amp;旅行。如果您想要一个工资单模块,您可能只使用公司,员工和&amp;人。所以你需要以下接口:

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())
{
    // ...
}