我有一个已使用数据库第一模型编码的SQL数据库的现有应用程序(每次更改模式时都会创建一个EDMX文件)。
已经完成了一些额外的开发(支持原始应用程序的Windows服务),它使用EF POCO / DbContext作为数据层而不是EF EDMX文件。在DbContexts中没有配置初始化设置,但它们从未修改数据库,因为DbSet对象始终与表匹配。
现在,我编写了一个单独的应用程序,它使用现有的数据库,但只使用自己的新表,它使用EFs初始化程序自行创建。我原以为这是使用EF Code First处理这些新表的好时机。我第一次运行应用程序时一切正常,但现在我从我的一些原始EF POCO DbContexts(从未使用过初始化程序)中得到了这个错误。
支持'ServerContext'上下文的模型自从以来发生了变化 数据库已创建。考虑使用Code First Migrations进行更新 数据库
经过一番调查,我发现EF将其架构的哈希值与sql server中某些存储的哈希值进行了比较。在上下文实际上在数据库上使用初始化程序之前,该值不存在(在我的情况下,直到最近的应用程序添加其表)。
现在,我的其他DbContexts会在读取现有哈希值时抛出错误,但它与自己的哈希值不匹配。使用EDMX的EF连接没有任何错误。
似乎解决方案是将此行放在protected override void OnModelCreating(DbModelBuilder modelBuilder)
中遇到问题的所有DbContexts
Database.SetInitializer<NameOfThisContext>(null);
但是,如果稍后我想编写另一个应用程序并让它首先使用EF代码创建自己的表,那么现在我将永远无法协调这个理论甚至更新的上下文与导致现在问题。
有没有办法清除EF存储在数据库中的哈希值? EF足够聪明,只能改变当前上下文中作为DbSet存在的表吗?任何见解都表示赞赏。
答案 0 :(得分:4)
是的,有界数据库上下文实际上是一种很好的做法。 例如,一个基本上下文类,使用公共连接到DB,每个子类,使用 Database.SetInitializer(NULL);正如你的建议。
然后继续并拥有一个具有“数据库视图”的大型上下文,并且此上下文负责所有迁移,并且只有上下文可以执行此操作。唯一的事实来源。
有多个上下文负责数据库迁移是一个噩梦我不认为你会解决。 与代码首次迁移创建的系统条目相混淆只能以泪流满面。
你在Julie Lerman视频中看到的主题正是你所描述的。 她建议的解决方案是单个“迁移”上下文,然后使用许多有界数据库上下文。
答案 1 :(得分:1)
您使用的EF版本是什么? EF Code First用于在EdmMetadata
表中存储SSDL的哈希值。然后在.NET Framework 4.3中,thingh改变了一点,EdmMetadata表被__MigrationsHistory
表替换(有关详细信息,请参阅this blog post)。但在我看来,你真正关心的是multi-tenant migrations,你可以使用同一个数据库拥有多个上下文。此功能已在EF6中引入 - (目前Aplpha2版本已公开)另请注意,EdmMetadata / __ MigrationHistory表特定于CodeFirst。如果您正在使用设计器(模型优先/数据库优先),则不会在数据库中存储其他信息,也不会检查EF模型是否与数据库匹配。这可能导致难以调试错误和/或数据损坏。