51

I created a "Code Only" POCO for use against an existing database using Entity Framework 4 and the CTP4. When I run a query I get the error

The model backing the 'xyzContext' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance. For example, the RecreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data.

I'm unclear on why this is happening or what I can change. I merely created the POCO, defined a simple DbContext, made a few tweaks, and then tried to run a simple query. Since I'm using "Code Only", I'm unaware of any configuration settings that need to be made. And I certainly don't want to recreate or delete the database since it's an existing database.

Thanks for any ideas.

Masoud
  • 8,020
  • 12
  • 62
  • 123
Donald Hughes
  • 6,627
  • 8
  • 35
  • 46

7 Answers7

80

I found the answer in the comments on this post on Scott Guthrie's blog.

http://weblogs.asp.net/scottgu/archive/2010/08/03/using-ef-code-first-with-an-existing-database.aspx

For those who are seeing this exception:

"The model backing the 'Production' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance."

Here is what is going on and what to do about it:

When a model is first created, we run a DatabaseInitializer to do things like create the database if it's not there or add seed data. The default DatabaseInitializer tries to compare the database schema needed to use the model with a hash of the schema stored in an EdmMetadata table that is created with a database (when Code First is the one creating the database). Existing databases won’t have the EdmMetadata table and so won’t have the hash…and the implementation today will throw if that table is missing. We'll work on changing this behavior before we ship the fial version since it is the default. Until then, existing databases do not generally need any database initializer so it can be turned off for your context type by calling:

Database.SetInitializer<Production>(null);
Community
  • 1
  • 1
Donald Hughes
  • 6,627
  • 8
  • 35
  • 46
  • 4
    Ive just had the this exact same problem in 2013 with EF5 fixed by your answer. So did they not fix it for some very good reason, is there a new pattern for EF5? – rism Mar 18 '13 at 10:10
  • 2
    FYI had this same issue with EF6, which was suprising. This answer solved my issue (integrated asp.net identity-generated tables on top of my pre-existing sql server database). – Rachael May 30 '14 at 21:46
  • 3
    Using EF6, I just updated the database by hand and dropped the migration table. – Simon MᶜKenzie Aug 01 '14 at 07:51
  • 3
    The table I dropped to fix the problem was __MigrationHistory from a previous sample build I had. This solved the issue. – CoderRoller Jan 16 '15 at 20:50
  • EF 6, I haven't changed anything at all but started to get this error :S I have no idea that to do!? – hakan Sep 28 '15 at 17:45
  • 1
    @CoderRoller, exactly! Dropping __MigrationHistory table has fixed the issue. – Anton Lyhin Apr 09 '16 at 12:20
  • 1
    Where do you put the line `Database.SetInitializer(null);` – M Kenyon II Sep 15 '16 at 17:20
32

This is a bug in CTP4 for using EF with pre-existing databases.

You can fix it by calling:

Database.SetInitializer<YourContext>(null);

in the Application_Start method of Global.asax

sth
  • 222,467
  • 53
  • 283
  • 367
Steve Lydford
  • 428
  • 5
  • 7
  • I am using MVC3. I have added an extra column to the model class. I also entered your code within global.asax. However I am still getting the error. I don't think old db is dropped or re-created. How can I add a new column to the model and drop and recreate the db? – bonCodigo Sep 30 '14 at 10:39
  • `protected void Application_Start()` `{` `Database.SetInitializer(null);` `AreaRegistration.RegisterAllAreas();` `RegisterGlobalFilters(GlobalFilters.Filters);` `RegisterRoutes(RouteTable.Routes);` `}` – bonCodigo Sep 30 '14 at 10:39
  • Downvoted because the question is not an asp.net question – Jared Beach Jun 14 '16 at 15:11
13

I commented above and it worked at the time when I just playing around with EF5 to familarise myself with it's workings. Now I'm writing "actual" code and I've moved away from setting a database initialiser per context in code because of a architecture I've settled on using MEF to instantiate any DbContext and inject all configuration dependencies as composable parts.

So again I immediately ran into the error described above but this time I choose to resolve it using configuration file entries as below.

<entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
    <contexts>
      <context type="Basd.Erp.ContactContext, Basd.Erp" disableDatabaseInitialization="true"></context>
    </contexts>
  </entityFramework>

So by setting disableDatabaseInitialization="true" in the config file section for entityFramework you can overcome the error described above and since it's not in code one of the benefits is the ability to "more easily" use abstracted builders/factories to create context.

rism
  • 11,932
  • 16
  • 76
  • 116
  • I still had this issue in EF6 when my context was in separate assembly. This is a good answer as @rism suggested for abstracted 'n-tier' solutions. – trevorc Aug 01 '15 at 13:32
4

All I had to do to was drop the __MigrationHistory table.

Context:

I received this error when I changed the name of a table. After I added the annotation [Table("NewTableName")] to one of my models, Entity Framework generated a __MigrationHistory table.

Jared Beach
  • 2,635
  • 34
  • 38
1

I had the same issue - re-adding the migration and updating the database didn't work and none of the answers above seemed right. Then inspiration hit me - I'm using multiple tiers (one web, one data, and one business). The web layer never threw this exception - it was the business layer (which I set as console application for testing and debugging). Turns out the business layer wasn't using the right connection string to get the db and make the context. So I added the connection string to the app config and viola it works. Putting this here for others who may encounter the same issue.

Richard Barker
  • 1,161
  • 2
  • 12
  • 30
  • 1
    Thanks for this! Had to look through a lot of these post until I found a solution that worked for me; too bad it had to be an embarrassingly simple one – MichaelM Jul 25 '18 at 14:09
1

This was resolved for me by adding this to by context constructor.

Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>());

After doing this my code-first migrations now run automatically when the db already exists.

Justin
  • 1,303
  • 15
  • 30
0

For this Error in my case, i just deleted all records on "_MigrationHistory" Table, from "DBControlContext". I hope this is helpful.