仅实体框架代码错误:支持上下文的模型自创建数据库以来已更改
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<MVCMovie1.Models.MovieDBContext>(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 迁移来更新数据库