实体框架6.0代码优先迁移-模型/数据库兼容性错误

本文关键字:模型 数据库 错误 兼容性 迁移 框架 代码 实体 | 更新日期: 2023-09-27 18:12:13

在当前的项目中,我使用实体框架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())

…在这种情况下,即:false。

如果我现在运行初始化器并且我的数据库还不可用,那么所有的东西都按照它应该的方式创建,并且CompatibleWithModel函数返回-如预期的那样:true。

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

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

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

这是一个bug吗?

实体框架6.0代码优先迁移-模型/数据库兼容性错误

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

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

现在,当你删除__MigrationsHistory时,你正在使实体框架认为你正在使用代码优先到现有数据库方法。从这一刻起,实体框架将假定是你负责保持数据库和模型同步。这种情况下,Database.CompatibleWithModel方法的行为取决于throwIfNoMetadata参数的值。如果throwIfNoMetadata设置为true,那么如果在与上下文关联的模型中或在数据库本身中没有找到模型元数据,则会抛出异常。如果设置为false,则如果未找到元数据,该方法将返回true。