3

Currently I am building a web application with MVC 4 and Entity Framework code first scenario.

In the main structure of my application, I have a Dbcontext(BlogDB) to manage some Blog classes. It works fine as it created all the tables I need in the database. Then I created a Area to host an online store. My idea is to create a separated DbContext class(OnlineStoreDB) to handle the classes used for Online Store only.

My problem is once the OnlineStoreDB is fired, entity framework not only created tables for OnlineStore BUT ALSO removed old tables.

My questions are:

  1. If you know a way to keep the old tables?
  2. How exactly to manage the multi EF context classes in one application?

Code:

public class BlogDB : DbContext
{
    public BlogDB ()
        : base("DBConnection")
    {
        Database.SetInitializer(new BlogInitializer());
    }

    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Author> Authors { get; set; }
    public DbSet<Comment> Comments { get; set; }
}

public class OnlineStoreDB : DbContext
{
    public OnlineStoreDB() :
        base("DbConnection")
    {
        Database.SetInitializer(new OnlineStoreInitializer());
    }

    public DbSet<Order> Orders { get; set; }
    public DbSet<Product> Products { get; set; }
    public DbSet<User> Users { get; set; }
}
Dave Alperovich
  • 32,320
  • 8
  • 79
  • 101
Xavier
  • 389
  • 7
  • 20
  • Code-First will be a challenge. but why do you need to contexts? can't you just create all your POCOs in one contxt? if not, I'd recommend a factory object. Good luck! – Dave Alperovich Jan 23 '13 at 03:58

2 Answers2

3

Xavier, welcome to code-first!

Yes, code-first was a brilliant approach that promised soooo much. But now you've hit the catch. There's no clever mind at Microsoft (or outside as far as I know) who has come up with a smooth way to alter tables intelligently without endangering the data and possibly schema.

2 Years ago, the implementation strategy was to drop and re-build the DB. That was just intolerable as many of us didn't have SU access and were stopped in our tracks.

For all the advantages I found from code first, I prefer DB first. While data can't be preserved easily, annotations can through buddy classes.

Microsoft has come up with some clever Migration Strategies. I strongly suggest you read both articles. Code Project 2nd:

1) http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-code-based-migrations-walkthrough.aspx

2) http://www.codeproject.com/Articles/504720/EntityplusFrameworkplusCodeplusFirstplusMigrations

whether you decide to continue with Code-First, they should be enlightening. I sound like a critic but I'm torn between advantages of one and stability of the other.

Finally, I don't think you should preserve 2 dbcontexts. Your POCOs should be consolidated under 1 context.

Dave Alperovich
  • 32,320
  • 8
  • 79
  • 101
  • 3
    I too am old-school, and prefer designing my database schema first. – Robert Harvey Jan 23 '13 at 03:58
  • 1
    Thanks Dave, I am thinking that the code first is just a headache sometimes. I did migration and that's why the old tables for BlogDB are gone. You are right, I can only solve the problem by deleting the entire database from sql server and run the application again. Will switch to DB first. – Xavier Jan 23 '13 at 04:31
  • good luck Xavier! I went thru exactly same process and it sucked. If you haven't yet, read up on buddy classes. Clever way to preserve data annotations on POCOs inspite of the constant rebuilding. – Dave Alperovich Jan 23 '13 at 04:33
  • @DaveA do you have some good examples of the usage of buddy classes? thanks – Xavier Jan 23 '13 at 05:03
  • @Xavier, near the bottom of this post is an example. http://jameschambers.com/2011/08/automatic-generation-of-metadata-buddy-classes/ – Dave Alperovich Jan 23 '13 at 05:16
  • the concept is clever. Since POCOs are generated as partial classes and their members virtuals, create partial classes with same name for each POCO including each member that you want annotated. The example makes it very clear. much more obvious than my explanation. – Dave Alperovich Jan 23 '13 at 05:18
1

If you want to keep the tables not changed you need to set initializer to null in both DBContexts if they have sub set of tables .

But I don't see a point that you create two DBContexts for one database. Can you clearly separate two set of tables(Domains) in you database?

Jayantha Lal Sirisena
  • 21,216
  • 11
  • 71
  • 92
  • Hi Jayantha, I conbimed all the DBSets in one DBContext, deleted the database from sql server, re-run the application and it works fine only. However, do you know an example to handle two DBContexts in one project? – Xavier Jan 23 '13 at 04:34