简体   繁体   中英

Entity Framework 6.0 Code First Migration - Model/Database compatibility bug?

In a current project, I use Entity Framework 6.0 alpha3 with code first approach. I have a custom data context that takes a DbConnection in the constructor to access it's database. My migrations are done either in VisualStudio or with the MigrationToLatestVersion initializer during runtime.

Sample:

public class MyStackOverflowSampleContext : DbContext {

    DbSet<Question> Questions { get; set; }
    DbSet<Answers>  Answers   { get; set; }

    public MyStackOverflowSampleContext(DbConnection connection)
    : base(connection) { }

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

I check the database model using the following

if(_dbContext.Database.CompatibleWithModel())

... which is, in that case: false.

If I now run the initializer and my database isn't available yet, everything get's created the way it should and the CompatibleWithModel function returns - as expected: true.

Now, for testing purposes, I changed the database behind, first slightly, then completely. I delete a column, then a whole table and even the _MigrationsHistory table.

But whatever I do: _dbContext.Database.CompatibleWithModel() always returns true! And when I try to initialize the context, weird errors occur, eg: " The table TabAnswers already exists in database. " - even if it doesn't exist anymore.

But when I try to update to restore my database: " There are currently no pending updates... "

Is this a bug?

The behaviour you are seeing is correct from Entity Framework point of view, you just assume that Entity Framework is smarter than it is.

The only way in which Entity Framework determines if model is compatible with database is by comparing the hash stored by your context and the has stored in __MigrationsHistory table. This is why droping a column or table doesn't make Database.CompatibleWithModel return false - the hashes are still the same.

Now when you are deleting __MigrationsHistory , you are making Entity Framework think that you are using Code First to an Existing Database approach. From this moment Entity Framework will assume that it is you who is reponsible for keeping database and model in sync. The behaviour of Database.CompatibleWithModel method in that case depends on the value of throwIfNoMetadata parameter. If throwIfNoMetadata is set to true then an exception will be thrown if no model metadata is found either in the model associated with the context or in the database itself. If set to false then the method will return true if metadata is not found.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM