Reputation: 1637
VS2013, EF6 code first, 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.
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.
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.
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:
Cons of a single context:
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.
Thanks for the input.
Best Regards, Alan
Upvotes: 12
Views: 6107
Reputation: 9153
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).
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.
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).
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.
Upvotes: 7
Reputation: 239290
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.
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.
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
:
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.
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.
Upvotes: 9