仅实体框架代码错误:支持上下文的模型自创建数据库以来已更改

Posted

技术标签:

【中文标题】仅实体框架代码错误:支持上下文的模型自创建数据库以来已更改【英文标题】:Entity Framework Code Only error: the model backing the context has changed since the database was created 【发布时间】:2010-08-23 21:52:01 【问题描述】:

我创建了一个“仅代码”POCO,用于使用 Entity Framework 4 和 CTP4 对现有数据库。当我运行查询时,我收到错误

支持“xyzContext”上下文的模型在创建数据库后发生了变化。手动删除/更新数据库,或使用 IDatabaseInitializer 实例调用 Database.SetInitializer。例如,RecreateDatabaseIfModelChanges 策略将自动删除并重新创建数据库,并可选择为其添加新数据。

我不清楚为什么会发生这种情况或我可以改变什么。我只是创建了 POCO,定义了一个简单的 DbContext,做了一些调整,然后尝试运行一个简单的查询。由于我使用的是“仅代码”,因此我不知道需要进行任何配置设置。而且我当然不想重新创建或删除数据库,因为它是一个现有的数据库。

感谢您的任何想法。

【问题讨论】:

【参考方案1】:

我在 Scott Guthrie 博客上这篇文章的 cmets 中找到了答案。

http://weblogs.asp.net/scottgu/archive/2010/08/03/using-ef-code-first-with-an-existing-database.aspx

对于看到此异常的人:

“支持 'Production' 上下文的模型自创建数据库以来已更改。手动删除/更新数据库,或使用 IDatabaseInitializer 实例调用 Database.SetInitializer。”

这是发生了什么以及如何处理它:

第一次创建模型时,我们会运行 DatabaseInitializer 来执行诸如创建数据库(如果数据库不存在)或添加种子数据等操作。默认的 DatabaseInitializer 尝试将使用模型所需的数据库架构与存储在使用数据库创建的 EdmMetadata 表中的架构哈希进行比较(当 Code First 是创建数据库的人时)。现有的数据库不会有 EdmMetadata 表,因此不会有哈希……如果该表丢失,今天的实现将抛出。在我们发布最终版本之前,我们将努力改变这种行为,因为它是默认的。在此之前,现有数据库通常不需要任何数据库初始化程序,因此可以通过调用以下方法为您的上下文类型关闭它:

Database.SetInitializer<Production>(null);

【讨论】:

我刚刚在 2013 年遇到了同样的问题,EF5 已由您的答案解决。那么他们没有修复它是不是有很好的理由,EF5 有新模式吗? 仅供参考,EF6 也有同样的问题,这令人惊讶。这个答案解决了我的问题(在我预先存在的 sql server 数据库之上集成了 asp.net 身份生成的表)。 使用 EF6,我只是手动更新了数据库并删除了迁移表。 我为解决问题而删除的表是我以前的示例构建中的 __MigrationHistory。这解决了问题。 @CoderRoller,没错!删除 __MigrationHistory 表已解决此问题。【参考方案2】:

这是 CTP4 中的一个错误,用于将 EF 与预先存在的数据库一起使用。

你可以通过调用来修复它:

Database.SetInitializer<YourContext>(null);

在 Global.asax 的 Application_Start 方法中

【讨论】:

我正在使用 MVC3。我在模型类中添加了一个额外的列。我还在 global.asax 中输入了您的代码。但是我仍然收到错误消息。我不认为旧数据库被删除或重新创建。如何向模型添加新列并删除并重新创建数据库? protected void Application_Start()Database.SetInitializer&lt;MVCMovie1.Models.MovieDBContext&gt;(null);AreaRegistration.RegisterAllAreas();RegisterGlobalFilters(GlobalFilters.Filters);RegisterRoutes(RouteTable.Routes); 投反对票,因为该问题不是 asp.net 问题【参考方案3】:

我在上面发表了评论,当时我只是在玩 EF5 以熟悉它的工作原理。现在我正在编写“实际”代码,并且我已经不再在代码中为每个上下文设置数据库初始化程序,因为我已经决定使用 MEF 实例化任何 DbContext 并将所有配置依赖项作为可组合部分注入。

所以我再次立即遇到了上述错误,但这次我选择使用如下配置文件条目来解决它。

<entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
    <contexts>
      <context type="Basd.Erp.ContactContext, Basd.Erp" disableDatabaseInitialization="true"></context>
    </contexts>
  </entityFramework>

因此,通过在 entityFramework 的配置文件部分中设置 disableDatabaseInitialization="true",您可以克服上述错误,并且由于它不在代码中,其中一个好处是能够“更轻松地”使用抽象的构建器/工厂来创建上下文。

【讨论】:

当我的上下文在单独的程序集中时,我在 EF6 中仍然遇到此问题。这是一个很好的答案,正如@rism 为抽象的“n 层”解决方案所建议的那样。【参考方案4】:

我所要做的就是删除__MigrationHistory 表。

上下文:

我在更改表名时收到此错误。在我将注释 [Table("NewTableName")] 添加到我的一个模型后,Entity Framework 生成了一个 __MigrationHistory 表。

【讨论】:

【参考方案5】:

我遇到了同样的问题 - 重新添加迁移和更新数据库不起作用,而且上面的答案似乎都不正确。然后灵感袭来——我正在使用多个层(一个网络、一个数据和一个业务)。 Web 层从未抛出此异常 - 它是业务层(我将其设置为用于测试和调试的控制台应用程序)。原来业务层没有使用正确的连接字符串来获取数据库并创建上下文。所以我将连接字符串添加到应用程序配置中,并且它可以工作。在这里为可能遇到相同问题的其他人提供。

【讨论】:

谢谢!在找到适合我的解决方案之前,我不得不浏览很多这些帖子;太糟糕了,它必须是一个令人尴尬的简单【参考方案6】:

通过上下文构造函数添加 this 为我解决了这个问题。

Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>());

执行此操作后,我的代码优先迁移现在会在数据库已经存在时自动运行。

【讨论】:

【参考方案7】:

对于我的这个错误,我刚刚从“DBControlContext”中删除了“_MigrationHistory”表上的所有记录。 我希望这会有所帮助。

【讨论】:

以上是关于仅实体框架代码错误:支持上下文的模型自创建数据库以来已更改的主要内容,如果未能解决你的问题,请参考以下文章

自创建数据库以来,支持“ApplicationDbContext”上下文的模型已更改

自创建数据库以来,支持上下文的模型已更改。考虑使用 Code First 迁移来更新数据库

在代码优先实体框架中手动编辑数据库

实体框架,无法创建类型为“XX”的常量值。此上下文仅支持原始类型或枚举类型

使用实体框架、代码优先和 CRUD 操作的存储库模式

实体框架 创建模型时无法使用上下文