【问题标题】: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,做了一些调整,然后尝试运行一个简单的查询。由于我使用的是“仅代码”,因此我不知道需要进行任何配置设置。而且我当然不想重新创建或删除数据库,因为它是一个现有的数据库。

感谢您的任何想法。

【问题讨论】:

    标签: c# .net entity-framework entity-framework-4


    【解决方案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”表上的所有记录。 我希望这会有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-09-30
          • 2011-12-17
          • 1970-01-01
          • 1970-01-01
          • 2018-11-14
          • 2014-04-19
          • 2011-04-05
          • 2015-04-01
          相关资源
          最近更新 更多