entity-frameworkef-code-firstentity-framework-6entity-framework-migrations

Entity Framework : Sharing entities across different DbContexts


I'm developing a plugin application with EF6, code first.

I have one main context with an entity called User:

public class MainDataContext : DbContext
{
    public MainDataContext(): base("MainDataContextCS") {}
    public DbSet<User> Users { get; set; }
}

And then another context for PluginX, on another project which references the base one:

public class PluginDataContext : DbContext
{
    public PluginDataContext () : base("MainDataContextCS") {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.HasDefaultSchema("PluginX");
        base.OnModelCreating(modelBuilder);
    }

    public DbSet<Booking> Bookings { get; set; }
}

And this neatly creates, on the same Database (same connection string), the PluginX.Bookings Table.

The problem here is that the Booking entity contains a reference to User entity:

public class Booking
{
    public int Id { get; set;}
    public virtual User CreationUser { get; set;}
    public BookingStatus Status { get; set; }
}

And when running Add-Migration for the plugin context EF will try to create another User entity called PluginX.User.

How can this be solved? Is there a way to share a common entity, in another DbContext?


Solution

  • When you work with multiple contexts you have two options:

    1. Treat each context like they were separate applications. Imagine your user is an external resource that you get from a web service. You won't be able to add a foreign key to that. What you would do in this is either add only the userId in your tables and when you need the user details call the external service to get them or have a local light copy of the user in the Bookings context that you would update every now and then from the Users context. This approach is good when you work with a large system and you want to isolate the parts (read about DDD and bounded contexts)
    2. Apart from your 2 contexts, create a third context with the whole model (users, bookings, etc). You will use the complete context to create the migrations and maintain the DB structure, but in the application you will use the smaller contexts. This is a very simple solution. It's easy to maintain the migrations with a single context and it still allows you to isolate the DB operation in smaller contexts that don't have access to unrelated entities.