Splitting a DbContext into multiple contexts with overlapping DbSets

I have a DbContext that currently contains +80 objects and only 4 of the main modules are done, but there are three more and they are much more so it will go up to 150 easily. I think this is the perfect time to separate contexts. Each module uses its own entities and will get its own context, but there is a group of entities that are used by all modules, so the question is asked here:

Should I have one MainContext which will have all overlapping objects, but then:

  • What happens to FK dependencies?
  • How many performance problems will nesting using (var db = new context)

    have because I will need to access the main context from each module.

Should I put overlapping objects in all contexts, but then

  • What happens to the display, not every context will try to match its own entity and get an error?
  • Should you avoid showing overlapping contexts for all but one of the contexts?

Should I stay with one context?

Any other suggestions?

+3


source to share


1 answer


You will have problems if you need to use a transaction that spans more than one DbContext. This will facilitate a distributed transaction regardless of whether all DbContexts are connected to the same database. This makes things very slow.

You will also lose the unit of work advantage because DbContexts will keep track of its models on its own.

You can still split models and duplicate shared ones. This will not result in different DbContexts breaking relationships or deadlocking more than two people running two copies of your software at the same time.

However, to maintain controllability, you can stay in the same DbContext, but hide the models that are not needed in each module.

Take the next one 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> { get; set; }
}

      



If you want to create a control module, you can only use People, Cars and Trips. If you need a payroll module, you can only use company, employee and people. Thus, you will 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 DbContext

, just enter the variable, IDrivingContext

or IPayrollContext

, depending on which module you are coding inside:

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

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

      

+4


source







All Articles