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

Gre*_*eMD 5 c# dbcontext entity-framework-6

我有一个DbContext,目前可以容纳+80个实体,仅完成了4个主要模块,但还有3个要去,而且它们还很大,因此最多可以轻松完成150个。我认为现在是划分上下文的最佳时机。每个模块都使用自己的实体,并获得自己的上下文,但是所有模块都使用一组实体,所以这里是mu问题:

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

  • FK依赖关系将如何处理?
  • using (var db = new context)由于我需要从每个模块访问主上下文,因此将嵌套多少性能问题。

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

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

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

还有其他建议吗?

Kei*_*yne 6

如果您需要使用跨多个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> { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

如果要制作驱动模块,则只能使用“人,汽车和旅程”。如果需要薪资模块,则可以仅使用“公司”,“员工”和“人员”。因此,您将需要以下接口:

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; }
}
Run Code Online (Sandbox Code Playgroud)

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

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; }
}
Run Code Online (Sandbox Code Playgroud)

而且,当您使用时DbContext,只需将变量输入为IDrivingContextIPayrollContext,具体取决于您要在其中编码的模块:

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

using (IPayrollContext db = new MyDbContext())
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)