Entity Framework 6.0 Code First Migration - 模型/数据库兼容性错误?

时间:2013-05-06 11:30:15

标签: c# database entity-framework

在当前项目中,我使用Entity Framework 6.0 alpha3和代码优先方法。我有一个自定义数据上下文,它在构造函数中使用DbConnection来访问它的数据库。我的迁移可以在VisualStudio中完成,也可以在运行时使用MigrationToLatestVersion初始化程序完成。

样品:

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);
    }
}

我使用以下

检查数据库模型
if(_dbContext.Database.CompatibleWithModel())

...在这种情况下是假的。

如果我现在运行初始化程序并且我的数据库尚未可用,那么所有内容都会以它应该的方式创建并且CompatibleWithModel函数返回 - 正如预期的那样:true。

现在,出于测试目的,我将数据库稍后更改,然后完全更改。我删除了一列,然后是整个表,甚至是_MigrationsHistory表。

但无论我做什么:_dbContext.Database.CompatibleWithModel()总是返回真实!当我尝试初始化上下文时,会发生奇怪的错误,例如:&#34; The table TabAnswers already exists in database.&#34; - 即使它不再存在。

但是当我尝试更新以恢复我的数据库时:&#34; There are currently no pending updates...&#34;

这是一个错误吗?

1 个答案:

答案 0 :(得分:6)

从Entity Framework的角度来看,您所看到的行为正确,您只是假设实体框架比它更智能。

实体框架确定模型是否与数据库兼容的唯一方法是比较上下文存储的哈希值和__MigrationsHistory表中存储的哈希值。这就是为什么删除列或表不会使Database.CompatibleWithModel返回false - 哈希仍然是相同的。

现在,当您删除__MigrationsHistory时,您正在让实体框架认为您正在使用Code First to an Existing Database方法。从现在开始,Entity Framework将假设您负责保持数据库和模型同步。在这种情况下Database.CompatibleWithModel方法的行为取决于throwIfNoMetadata参数的值。如果throwIfNoMetadata设置为true,则如果在与上下文关联的模型中或在数据库本身中未找到模型元数据,则将引发异常。如果设置为false,则如果未找到元数据,则该方法将返回true。