5

I'm building an Asp.net MVC5 + EF6 solution with 3 projects. I have enabled automatic migration in my project. The below diagram shows my project structure.

enter image description here

  1. I have a main project and two sub projects.
  2. I have a BaseContext in a main project.
  3. Sub project has their own context classes which derives from BaseContext.
  4. All above contexts are connecting to one database.

Models:

A Model in Project2

public class Product
{
    [Key]
    public int ProductId {get;set;}
    ...
}

A Model in Project3

public class Order
{
    [Key]
    public int OrderId {get;set;}

    [ForeignKey("Product")]
    public int ProductId {get;set}

    public virtual Product Product;

    ...
}

An property from Project3 entity (Order.ProductId) references a property from Project2 entity (Product.ProductId) as a foreign key reference.

When I run update-databasecommand in project 1 & 2 everything is going well. But when run update-database command in project 3 It gives an error:

There is already an object named 'Product' in the database.

Right now I'm using update-database -script command to generate script and manually altering the script. But when project grows, it becomes a difficult task to alter sql scripts each and every time.

I ignored the Product entity by adding modelBuilder.Ignore<Product>() inorder to skip table creation for Productentity, in Project3, but it's ignores the entire relationship.

How can I solve this issue?

1
  • I have a similar problem where it is the same database, but added a new DB Context that includes new tables and some that are shared with the other DB Context. The 2 contexts are for different business problems. When I add a migration, EF 6 wants to create all the new tables, but also wants to create existing tables that reside in the older DB Context. I guess I may have to just edit the migration that EF is creating before doing the update-database. Or is there a better way? Commented Sep 26, 2019 at 21:18

1 Answer 1

3

You can't do this. One context == one database. When you run a migration against a database for a particular context, it will be based on that context, and will remove any non-applicable tables or try to drop and recreate the database.

You should move all your entities into a class library, along with a single instance of a context that includes them all. Then, you can migrate against the class library and simply reference in your other projects.

Alternatively, you can sort of do what you want by going with an existing database approach. Essentially, you turn off migrations entirely on your base context, and then each sub context can then only include the entities that belong to it. However, you're going to be completely responsible for managing the database, yourself, at that point.

public class BaseContext : DbContext
{
    public BaseContext()
        : base("ConnectionString")
    {
        Database.SetInitializer<BaseContext>(null);
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

I don't like to move all the entities to a class library. In my project's sub projects are class libraries. My main objective to separate them into multiple projects is to minimize the complexity when project grows larger. If One context == one database then what is the best practice to share the single context with multiple projects? How to make migration job easy in such situation?
You can separate out the entities into multiple class libraries if you want, but they still have to basically come together into one main class library that would include your context and simply reference all those other libraries. However, you'd still have an inherent dependency on each library in any app that needs the context, since the context library would have to reference all the others. In other words, this would only be for your own solution organization purposes. You couldn't simply pick or choose which entity projects are reference by which apps.
Again, that's the nature of code first with migrations. A single context must house every entity that belongs to the database it represents. Like I said early, you can sidestep this by simply not allowing EF to manage your database, and instead take that on yourself. Then, you can have as many contexts as you like, referencing whatever you like.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.