Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC3 / EF - Changing model... Database schema mismatch

I have been following the ASP.Net Movie Database Tutorial, and it was all going well.

I have just changed the model and added an attribute. Call me curious, but I didn't want to follow the guide of just drop the database - I wanted to see if I can modify.

The correct error came up about a mismatch - which was expected.

I added the ratings column to the database, and everything worked.

Next, I deleted the ratings column as I wanted to follow the tutorial and learn about DropCreateDatabaseIfModelChanges - however, I just get the error Invalid column name 'Ratings'.

In all this time, the ModelHash entry has not changed, and I have no idea how it know there is a difference between now or before.

So - 1) Have I screwed something up?

2) How can I fix?

3) How did it know before that something has changed, but not now when the hash hasn't changed?

4) Is there any additional advice you can give?

like image 519
Wil Avatar asked Mar 13 '11 16:03

Wil


1 Answers

I think you description must be incorrect because correct behavior will throw the exception despite of manually added Rating column.

This behavior works as follows:

  1. When database is created new table called EdmMetadata is added.
  2. EdmMetadata contains two columns - Id and ModelHash.
  3. Part of database creation is storing single row with hash of the current model.
  4. If database was not created by the current context the context executes a query to retrieve stored model hash before the first operation is executed. The retrieved has is compared with context's current hash.
  5. If hash is not the same and database recreation is not allowed by database initializer the exception is thrown.
  6. If hash is the same, required db operation is executed.

Adding manually Rating column will not change stored hash but hash of the model will be different.

This behavior can be completely removed by removing IncludeMetadataConvention convention:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Conventions.Remove(modelBuilder.Conventions
            .OfType<IncludeMetadataConvention>().ToArray());
    }
like image 144
Ladislav Mrnka Avatar answered Sep 28 '22 04:09

Ladislav Mrnka