Reputation: 2378
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:
Should I have one MainContext that will have all of the overlapping entities but then:
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?
Any other suggestions?
Upvotes: 6
Views: 5942
Reputation: 439
Splitting up the context is a better idea I think. It gives you the possibility to have lighter context and lighter context build times. Also if you make changes to a module, then it doesn't affect the whole database and you could for example only deploy part of the application. To keep the relations between objects in different contexts is difficult. You could handle this in the business layer and keep the Id's stored in the Database. If you cannot seperate the models in some way, then I guess you need to keep them together. The business layer is the place to handle business logic, there you could stop deleting entities there that are still linked. The database then will handle database logic like: types, sizes, identies, ... I am expetimenting with the split context myself. Started here: EF CORE: is it possible to support two models in one database? But mine are al lot more complex and also have overlapping entities like users are everywere (createdby, modifiedby, ...)
Upvotes: 0
Reputation: 3082
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.
You will also lose the benefit of the unit of work because the DbContexts will track their models independently.
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.
However, to keep things manageable you can stay in one DbContext, but hide the models that are not needed in each module.
Take the following 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; }
}
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; }
}
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())
{
// ...
}
Upvotes: 9