将 DbContext 拆分为具有重叠 DbSet 的多个上下文 [英] Splitting DbContext into multiple contexts with overlapping DbSets

查看:18
本文介绍了将 DbContext 拆分为具有重叠 DbSet 的多个上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a DbContext that houses +80 entities at the moment with only 4 of the main modules done, but there are 3 more to go, and they are quite bigger so it will get up to 150 easy. I think it is the perfect time to divide the contexts. Every module uses it's own entities and will get it's own context, but there is a group of entities that are used by all of the modules, so here is mu question:

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

Should I have one MainContext that will have all of the overlapping entities but then:

  • FK 依赖项会发生什么?
  • 嵌套 using (var db = new context) 会有多少性能问题,因为我需要从每个模块访问主上下文.
  • What will happen to the FK dependencies?
  • How much of a performance issue would be to have nested using (var db = new context) because I will need to access the main context from every module.

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

Should I put the overlapping entities in all of the contexts, but then

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

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

Should I stay with one context?

还有其他建议吗?

推荐答案

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

You will have problems if you need to use a transaction that spans more than one DbContext. It will be promoted to a distributed transaction no matter if all of the DbContexts connect to the same database. This makes things very slow.

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

You will also lose the benefit of the unit of work because the DbContexts will track their models independently.

您仍然可以分离模型并复制共享模型.这不会导致各种 DbContext 破坏关系或陷入僵局,不会超过两个人同时运行您的软件的两个副本.

You could still separate the models and duplicate the shared ones. This will not cause the various DbContexts to break relationships or deadlock any more than two people running two copies of your software at the same time would.

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

However, to keep things manageable you can stay in one DbContext, but hide the models that are not needed in each module.

取下面的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 和旅行.如果你想要一个工资单模块,你可能只使用 Company、Employee 和 &人们.所以你需要以下接口:

If you wanted to make a driving module, you might only use People, Cars, & Trips. If you wanted a payroll module, you might only use Company, Employee, & People. So you would need the following interfaces:

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; }
}

然后你改变你的上下文来实现这两个接口:

Then you change your context to implement both interfaces:

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,具体取决于您在哪个模块中编码:

And when you use the DbContext, only type the variable as IDrivingContext or IPayrollContext, depending on which module you are coding inside of:

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

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

这篇关于将 DbContext 拆分为具有重叠 DbSet 的多个上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆