【问题标题】:Model backing a DB Context has changed; Consider Code First Migrations支持数据库上下文的模型已更改;考虑代码优先迁移
【发布时间】:2013-02-19 01:12:44
【问题描述】:

支持“MyDbContext”上下文的模型在创建数据库后发生了变化。考虑使用 Code First 迁移来更新数据库 (http://go.microsoft.com/fwlink/?LinkId=238269)。

是什么导致这种情况发生?我实际上只是创建了一个全新的数据库并且没有进行任何更改,但是每次我尝试从控制器访问模型时都会抛出这个。

编辑

这与我试图与两个单独的实体共享连接字符串(即数据库)这一事实有关。

【问题讨论】:

  • 只要两个实体都在同一个 DbContext 中,那么这应该不是问题。您将 DbContext 配置为使用连接字符串,所有实体都将使用它。
  • 我也遇到过同样的问题,但我的解决方法是在包管理器控制台中启用迁移。我不知道为什么会这样。
  • 这通常发生在您的上下文类 DbContext 更改为 IdentityDbContext

标签: asp.net-mvc entity-framework


【解决方案1】:

在我的例子中,这个错误是由数据库中存在 _MigrationsHistory 表引起的。删除该表解决了这个问题。不确定该表是如何进入我们的测试环境数据库的。

【讨论】:

  • 这对我来说是最快的解决方案。我在表中添加了 1 个新的 bit 列,并向我的 C# 模型添加了相应的属性。我不想删除所有数据并重置所有内容,所以我只是删除了这个 _Migrations 历史表,它在 C# 中拾取了新列就好了。
  • 同样的交易;我很担心我必须做的所有代码优先迁移的事情,而显然我似乎没有。删除 _MigrationsHistory 表也为我清除了一切!
  • 解决了我的问题。谢谢
  • 那张桌子到底是干什么用的?为什么我们需要它?
  • 我也是你的情况!不明白它工作的原因!
【解决方案2】:

EF codefirst 将查看您的 DbContext,并发现其中声明的所有实体集合(并通过导航属性查看与这些实体相关的实体)。然后它会查看你给它一个连接字符串的数据库,并确保那里的所有表都与模型中实体的结构相匹配。如果它们不匹配,则它无法读取/写入这些表。每当您创建一个新数据库,或者如果您更改实体类声明的某些内容,例如添加属性或更改数据类型,那么它会检测到模型和数据库不同步。默认情况下,它只会给您上述错误。通常在开发过程中,您希望重新创建数据库(擦除任何数据)并从您的新模型结构中再次生成。

为此,请参阅本文中的“RecreateDatabaseIfModelChanges 功能”: http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx

您基本上需要提供一个继承自 DropCreateDatabaseIfModelChanges 的数据库初始化程序(现在不推荐使用 RecreateDatabaseIfModelChanges)。为此,只需将此行添加到 Global.asax 文件的 Application_Start 方法即可。

Database.SetInitializer<NameOfDbContext>(new DropCreateDatabaseIfModelChanges<NameOfDbContext>());

一旦您进入生产环境并且不想再丢失数据,那么您将删除此初始化程序并改为使用数据库迁移,这样您就可以在不丢失数据的情况下部署更改。

【讨论】:

  • RecreateDatabaseIfModelChanges 现在是 DropCreateDatabaseIfModelChanges: See this post
  • 我正在使用一个已经存在多年的数据库,并且许多其他系统都依赖于该数据库,因此我根本无法更改该数据库上的任何内容。实际上,在我 13 年的专业开发生涯中,我从来没有参与过一个我们可以因为 som 代码更改而只更改数据库的项目。我将如何解决同样的错误?
  • @AxelAndersen 如果您对变更集进行源代码控制检查更改并确定更改了哪些实体,则回滚该实体。您还可以使用“EF 迁移”来生成 SQL 更改脚本,以帮助您了解它试图更改的内容,从而帮助您确定哪些 EF 实体不同步。如果您不想更改 DB,则无法更改 EF 实体类。
  • @AaronLS 我实际上并没有改变任何现有的东西,我正在尝试手动创建一个与数据库表匹配的新类。这不应该吗?
  • @AxelAndersen 我建议您使用 EF 迁移来生成更改脚本以确定 EF 尝试进行哪些更改。 即使您使用单个表进行测试,一旦您在现有项目中拥有新表,那么 EF 检测到的潜在隐含关系/FK 需要部署而您的数据库没有。试图猜测是没有意义的。您可以使用一种工具来揭示差异是什么。然后,如果您需要帮助修改模型以消除差异,请发布一个关于 EF 模型和生成的更改脚本的新问题。
【解决方案3】:

要解决此错误,请在 Global.asax.cs 文件的 Application_Start() 方法中编写以下代码

Database.SetInitializer<MyDbContext>(null);

【讨论】:

  • 这是解决问题还是只是隐藏症状?
  • 也许它会阻止 ERM 接触数据库(有时这正是我们想要的)。不知道具体做了什么。
  • 这个答案在使用 context.Entities.SqlQuery("") 调用存储过程时特别有用。
  • 天才!谢谢!
  • 当我使用现有表并且我不想使用模型中的所有字段时,这实际上很有帮助。
【解决方案4】:

如果您对上下文进行了更改,并且想要手动对 DB 进行相关更改(或保持原样),则有一种快速而肮脏的方法。

转到数据库,从“_MigrationHistory”表中删除所有内容

【讨论】:

    【解决方案5】:

    最简单安全的方法 如果您知道您确实想更改/更新您的数据结构,以便数据库可以与您的 DBContext 同步,最安全的方法是:

    1. 打开您的包管理器控制台
    2. 类型:update-database -verbose -force

    这告诉 EF 对您的数据库进行更改,使其与您的 DBContext 数据结构相匹配

    【讨论】:

    • 谢谢。这真的很有帮助。
    【解决方案6】:

    只需转到包管理控制台,输入以下内容:

    启用迁移

    *如果出现这样的错误“无法更新数据库以匹配当前模型,因为有待处理的更改并且自动迁移被禁用。要么将待处理的模型更改写入基于代码的迁移,要么启用自动迁移。”

    执行此操作 >>> 添加迁移

    *Visual Studio 会询问名称,请输入您想要的名称。

    更新数据库

    【讨论】:

      【解决方案7】:

      将此添加为另一种可能的解决方案,因为这是在我们的案例中修复它的原因;

      确保您有多个项目使用相同的 Entity Framework Nuget 包版本!

      在我们的例子中,我们有一个项目(如果项目 A 则调用)持有所有实体的 EF 代码优先上下文。我们使用这个项目来添加迁移和更新数据库。 但是,第二个项目 ( B ) 正在引用项目 A 以利用上下文。运行这个项目时,我们遇到了同样的错误;

      支持“MyDbContext”上下文的模型自数据库创建以来发生了变化。考虑使用 Code First 迁移来更新数据库 (http://go.microsoft.com/fwlink/?LinkId=238269)。

      【讨论】:

        【解决方案8】:

        您可以通过删除在数据库中自动创建并使用代码优先迁移记录数据库中的任何更新的__MigrationHistory 表来解决此问题。在这里,在这种情况下,您手动更改了数据库,而 EF 假设您必须使用迁移工具进行更改。删除表对 EF 意味着没有更新,也不需要进行代码优先迁移,因此它工作得非常好。

        【讨论】:

          【解决方案9】:

          当您的数据库与您的模型不同步时会发生此错误,反之亦然。要克服这个问题,请按照以下步骤操作 -

          a) 使用 add-migration 添加迁移文件 nuget 包管理器控制台。此迁移文件将包含用于同步 Db 和代码之间不同步的任何内容的脚本。

          b) 使用 update-database 命令更新数据库。这将更新 具有模型中最新更改的数据库。

          如果这没有帮助,请在 Global.asax.cs 文件的 Application_Start 方法中添加这行代码后尝试这些步骤 -

          Database.SetInitializer<VidlyDbContext>(new DropCreateDatabaseIfModelChanges<VidlyDbContext>());
          

          参考 - http://robertgreiner.com/2012/05/unable-to-update-database-to-match-the-current-model-pending-changes/

          【讨论】:

            【解决方案10】:

            当您的表结构和模型类不再同步时会发生这种情况。您需要根据模型类更新表结构,反之亦然——这是您的数据很重要且不能删除的时候。如果您的数据结构已更改并且数据对您不重要,您可以通过在 Global.asax.cs 中添加以下代码来使用 DropCreateDatabaseIfModelChanges 功能(以前称为“RecreateDatabaseIfModelChanges”功能)

            Database.SetInitializer<MyDbContext>(new DropCreateDatabaseIfModelChanges<MyDbContext>());
            

            再次运行您的应用程序。

            顾名思义,这将删除您的数据库并根据您最新的模型类(或多个类)重新创建——前提是您相信模型类中的表结构定义是最新和最新的;否则请更改模型类的属性定义。

            【讨论】:

              【解决方案11】:

              如果您使用已存在的表更改了模型和数据库,并且收到错误“支持数据库上下文的模型已更改;请考虑代码优先迁移”,您应该:

              • 删除项目中“迁移”文件夹下的文件
              • 打开包管理器控制台并运行pm&gt;update-database -Verbose

              【讨论】:

                【解决方案12】:

                Entity Framework 检测到模型发生了一些变化,你需要对数据库做一些事情来完成这项工作。解决方案:1。启用迁移2。更新数据库

                【讨论】:

                  【解决方案13】:

                  你需要相信我。 我收到此错误的原因很简单,因为我忘记在您的启动项目的 App.Config(我的是一个 wpf 项目)中添加连接字符串。

                  以我为例的整个配置

                  <?xml version="1.0" encoding="utf-8"?>
                  <configuration>
                    <configSections>
                      <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
                      <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
                    </configSections>
                    <connectionStrings>
                      <add name="ZzaDbContext" connectionString="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=ZaaDbInDepth;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False" providerName="System.Data.SqlClient"/>
                    </connectionStrings>
                    <startup>
                      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
                    </startup>
                    <entityFramework>
                      <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
                        <parameters>
                          <parameter value="mssqllocaldb" />
                        </parameters>
                      </defaultConnectionFactory>
                      <providers>
                        <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
                      </providers>
                    </entityFramework>
                  </configuration>
                  

                  【讨论】:

                    【解决方案14】:

                    如果你使用身份,可能你的上下文名称不同于migrationHistory last record context Key。因此,您需要在这部分代码中更改名称,并在 ContextKey 中使用新名称:

                             Database.SetInitializer<ContextName>(null);
                    

                    【讨论】:

                      猜你喜欢
                      • 2015-02-15
                      • 2015-02-13
                      • 2014-03-25
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多