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?
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())
{
// ...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With