使用单个或多个DbContext与EF的优缺点是什么?

时间:2021-02-01 13:57:32

VS2013, EF6 code first, MVC, (VB)

VS2013,EF6代码优先,MVC,(VB)

I wanted to better understand the pros and cons of using either a single context, or splitting DbSets into multiple contexts. I have been reading through some of the old SO posts on multiple DbContexts and didn't really find what I was looking for; a comprehensive statement on when and where to use or not use multiple DbContexts.

我想更好地理解使用单个上下文或将DbSets拆分为多个上下文的优缺点。我一直在阅读多个DbContexts上的一些旧SO帖子,并没有找到我想要的东西;关于何时何地使用或不使用多个DbContexts的综合声明。

In the case of a single user running a program such as Windows Forms on their own hardware, it would seem there is no reason to have multiple contexts for ease of working with the code.

对于单个用户在自己的硬件上运行Windows Forms等程序的情况,似乎没有理由为了便于使用代码而有多个上下文。

In the case of a web application that runs a major business program for multiple businesses it would seem multiple DbContexts are essential for security and administration.

对于运行多个业务的主要业务程序的Web应用程序,似乎多个DbContexts对于安全性和管理是必不可少的。

But I'd like to get confirmation if I'm thinking about this question correctly. All I can think of is the following, but then I'm quite new to this environment:

但是如果我正确地思考这个问题,我想得到确认。我能想到的只有以下几点,但后来我对这个环境很陌生:

Pros of a single context:

单一背景的优点:

  • Coding only has a single context to deal with
    • (Are there issues with relationships across contexts?)
    • (跨上下文的关系是否存在问题?)

  • 编码只有一个上下文要处理(跨上下文的关系是否有问题?)

  • Migrations are easier because there is only one migration folder and process
  • 迁移更容易,因为只有一个迁移文件夹和进程

  • Easier to get a comprehensive diagram constructed in SSMS or EDMX
    • (Link here for getting EDMX diagrams when using code first)
    • (链接此处首先使用代码获取EDMX图表)

  • 更容易获得在SSMS或EDMX中构建的综合图表(在此处链接以获取首先使用代码时的EDMX图表)

Cons of a single context:

单一背景的缺点:

  • Security might be an issue for multiple web clients on an enterprise app
    • (Is this an issue for simple websites that have simple memberships?)
    • (对于拥有简单会员资格的简单网站,这是一个问题吗?)

  • 对于企业应用程序上的多个Web客户端,安全性可能是一个问题(对于具有简单成员身份的简单网站,这是一个问题吗?)

  • Some SO posts seem to suggest response time is an issue
    • (What is the mechanism here?)
    • (这里的机制是什么?)

  • 一些SO帖子似乎表明响应时间是一个问题(这里的机制是什么?)

That's all I have. I don't know enough to fully understand the two sides, and given the different environments we can be working in, it would seem the answer to one or multiple contexts will be different.

这就是我的全部。我完全不了解双方,并且考虑到我们可以使用的不同环境,似乎一个或多个环境的答案会有所不同。

I'm currently working on a website that will have memberships, and also a downloadable app which will be a personal app running on the user's hardware. In this case I think a single context for both makes sense, but before I get too deep into it, I though I would ask for some discussion on this. I presume others who are somewhat new to the environment will continue to have the same questions.

我目前正在开发一个拥有会员资格的网站,还有一个可下载的应用程序,它将是一个在用户硬件上运行的个人应用程序。在这种情况下,我认为两者的单一上下文都是有道理的,但在我深入研究之前,我会请求对此进行一些讨论。我认为对环境有些新意的其他人会继续遇到同样的问题。

I also note that Microsoft saw fit to add multiple context capability to EF in EF6 and higher, so clearly there must be some programming environments that give rise to compelling reasons to have multiple contexts.

我还注意到微软认为在EF6及更高版本中为EF添加多个上下文功能是合适的,所以显然必须有一些编程环境能够产生令人信服的理由来拥有多个上下文。

Thanks for the input.

感谢您的投入。

Best Regards, Alan

最诚挚的问候,艾伦

2 个解决方案

#1


6  

The only good reason to have multiple contexts, in my opinion, is if you have multiple databases in play. One application I work with has 3 contexts, for example. Two contexts are for existing databases that the application is not directly responsible for, while the third is the application-specific context with migrations.

在我看来,拥有多个上下文的唯一好理由是,如果您有多个数据库在运行。例如,我使用的一个应用程序有3个上下文。两个上下文适用于应用程序不直接负责的现有数据库,而第三个上下文是具有迁移的特定于应用程序的上下文。

There's no real benefit to splitting a context. Erik suggests that large contexts have performance issues, but I've worked with a single context with 50+ object sets in it, and have noticed no performance problems at all.

拆分上下文没有什么好处。 Erik建议大型上下文存在性能问题,但我已经使用了包含50多个对象集的单个上下文,并且完全没有注意到性能问题。

However, on the flip-side, there's real detriments to working with multiple contexts. For one, you loose the ability to work with multiple objects seamlessly unless they all reside in the same context. Also, multiple contexts tend to confuse the heck out of green developers because of Entity Framework's object graph tracking. For example, let's say you had two entities, Foo and Bar, both in separate contexts. If you created a relationship to Bar on Foo:

然而,另一方面,使用多个上下文确实有害。首先,您无法无缝地处理多个对象,除非它们都位于相同的上下文中。此外,由于Entity Framework的对象图跟踪,多个上下文往往会混淆绿色开发人员。例如,假设您有两个实体,Foo和Bar,两者都在不同的上下文中。如果你创建了与Bar on Foo的关系:

public class Foo
{
    public virtual Bar Bar { get; set; }
}

Well, guess what? Both Foo and Bar are now tracked by Foo's context. If you then try to run migrations on both contexts, you'll get errors because Bar is managed in two, count 'em, two contexts.

好吧,猜猜怎么着? Foo和Bar现在都被Foo的上下文跟踪。如果您然后尝试在两个上下文中运行迁移,那么您将收到错误,因为Bar是以两个上下文计算的,两个上下文。

Mistakes like this are ridiculously easy to make, and you'll drive yourself nuts trying to keep everything totally excluded. Plus, my argument has always been that if you have entities in your project that you can completely exclude from others, then that's an argument for a totally separate project, not just a different context.

像这样的错误很容易制造,你会疯狂地试图让一切完全被排除在外。另外,我的观点一直是,如果你的项目中有实体可以完全排除其他实体,那么这就是一个完全独立的项目的论证,而不仅仅是一个不同的上下文。

#2


3  

I saw in the comments that you mentioned learning Domain Driven Design. One of the concepts in DDD is that of Bounded Contexts (be sure to check out the linked resource on bubble contexts to see how to deal with two contexts that share Entities).

我在评论中看到你提到了学习领域驱动设计。 DDD中的一个概念是有界上下文(请务必查看有关气泡上下文的链接资源,以了解如何处理共享实体的两个上下文)。

It makes absolute sense to map your bounded contexts using a separate DbContext for each. There are certain gotchas that you need to be wary of when doing this but following a DDD approach should help you avoid them. The primary is shared entities. One context should be responsible for controlling the lifecycle of the shared entities, the other should only query those entities and not make any changes to them.

使用单独的DbContext为每个映射有界上下文是绝对有意义的。在执行此操作时,您需要警惕某些陷阱,但遵循DDD方法应该可以帮助您避免它们。主要是共享实体。一个上下文应该负责控制共享实体的生命周期,另一个应该只查询这些实体而不对它们进行任何更改。

Separating your domain into bounded contexts will allow you to more easily manage a large/complex domain. It also avoids loading parts of the domain unnecessarily if you don't need them (in an SOA, you can deploy each bounded context autonomously as a service something that Udi Dahan calls an Autonomous Business Component).

将您的域划分为有界上下文将允许您更轻松地管理大型/复杂域。如果您不需要它,它还可以避免不必要地加载域的部分(在SOA中,您可以自主地将每个有界上下文部署为Udi Dahan称之为自治业务组件的服务)。

I wouldn't advocate doing the split until you have to. For example, multiple teams working with different parts of the domain at the same time might present a good opportunity to make the split but at some point it will definitely make sense to do so.

在你不得不这样做之前,我不会主张分裂。例如,同时处理域的不同部分的多个团队可能提供进行拆分的良好机会,但在某些时候这样做肯定是有意义的。

#1


6  

The only good reason to have multiple contexts, in my opinion, is if you have multiple databases in play. One application I work with has 3 contexts, for example. Two contexts are for existing databases that the application is not directly responsible for, while the third is the application-specific context with migrations.

在我看来,拥有多个上下文的唯一好理由是,如果您有多个数据库在运行。例如,我使用的一个应用程序有3个上下文。两个上下文适用于应用程序不直接负责的现有数据库,而第三个上下文是具有迁移的特定于应用程序的上下文。

There's no real benefit to splitting a context. Erik suggests that large contexts have performance issues, but I've worked with a single context with 50+ object sets in it, and have noticed no performance problems at all.

拆分上下文没有什么好处。 Erik建议大型上下文存在性能问题,但我已经使用了包含50多个对象集的单个上下文,并且完全没有注意到性能问题。

However, on the flip-side, there's real detriments to working with multiple contexts. For one, you loose the ability to work with multiple objects seamlessly unless they all reside in the same context. Also, multiple contexts tend to confuse the heck out of green developers because of Entity Framework's object graph tracking. For example, let's say you had two entities, Foo and Bar, both in separate contexts. If you created a relationship to Bar on Foo:

然而,另一方面,使用多个上下文确实有害。首先,您无法无缝地处理多个对象,除非它们都位于相同的上下文中。此外,由于Entity Framework的对象图跟踪,多个上下文往往会混淆绿色开发人员。例如,假设您有两个实体,Foo和Bar,两者都在不同的上下文中。如果你创建了与Bar on Foo的关系:

public class Foo
{
    public virtual Bar Bar { get; set; }
}

Well, guess what? Both Foo and Bar are now tracked by Foo's context. If you then try to run migrations on both contexts, you'll get errors because Bar is managed in two, count 'em, two contexts.

好吧,猜猜怎么着? Foo和Bar现在都被Foo的上下文跟踪。如果您然后尝试在两个上下文中运行迁移,那么您将收到错误,因为Bar是以两个上下文计算的,两个上下文。

Mistakes like this are ridiculously easy to make, and you'll drive yourself nuts trying to keep everything totally excluded. Plus, my argument has always been that if you have entities in your project that you can completely exclude from others, then that's an argument for a totally separate project, not just a different context.

像这样的错误很容易制造,你会疯狂地试图让一切完全被排除在外。另外,我的观点一直是,如果你的项目中有实体可以完全排除其他实体,那么这就是一个完全独立的项目的论证,而不仅仅是一个不同的上下文。

#2


3  

I saw in the comments that you mentioned learning Domain Driven Design. One of the concepts in DDD is that of Bounded Contexts (be sure to check out the linked resource on bubble contexts to see how to deal with two contexts that share Entities).

我在评论中看到你提到了学习领域驱动设计。 DDD中的一个概念是有界上下文(请务必查看有关气泡上下文的链接资源,以了解如何处理共享实体的两个上下文)。

It makes absolute sense to map your bounded contexts using a separate DbContext for each. There are certain gotchas that you need to be wary of when doing this but following a DDD approach should help you avoid them. The primary is shared entities. One context should be responsible for controlling the lifecycle of the shared entities, the other should only query those entities and not make any changes to them.

使用单独的DbContext为每个映射有界上下文是绝对有意义的。在执行此操作时,您需要警惕某些陷阱,但遵循DDD方法应该可以帮助您避免它们。主要是共享实体。一个上下文应该负责控制共享实体的生命周期,另一个应该只查询这些实体而不对它们进行任何更改。

Separating your domain into bounded contexts will allow you to more easily manage a large/complex domain. It also avoids loading parts of the domain unnecessarily if you don't need them (in an SOA, you can deploy each bounded context autonomously as a service something that Udi Dahan calls an Autonomous Business Component).

将您的域划分为有界上下文将允许您更轻松地管理大型/复杂域。如果您不需要它,它还可以避免不必要地加载域的部分(在SOA中,您可以自主地将每个有界上下文部署为Udi Dahan称之为自治业务组件的服务)。

I wouldn't advocate doing the split until you have to. For example, multiple teams working with different parts of the domain at the same time might present a good opportunity to make the split but at some point it will definitely make sense to do so.

在你不得不这样做之前,我不会主张分裂。例如,同时处理域的不同部分的多个团队可能提供进行拆分的良好机会,但在某些时候这样做肯定是有意义的。