1

在当前项目中,我使用 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()总是返回真!当我尝试初始化上下文时,会出现奇怪的错误,例如:“ The table TabAnswers already exists in database.” - 即使它不再存在。

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

这是一个错误吗?

4

1 回答 1

6

从实体框架的角度来看,您看到的行为是正确的,您只是假设实体框架比它更聪明。

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

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

于 2013-05-06T12:33:24.087 回答