EF数据迁移在添加新的迁移时无法检测到更改。

50
我正在使用Entity Framework 5.0数据迁移和Code First。当我向我的模型添加新字段并在程序包管理器控制台中执行以下命令时。
 "Add-migration AddedField"

我所得到的只是一个名为“n_AddedField”的空迁移,其中up和down方法不包含任何逻辑。

我尝试了很多方法,重新安装EF nuget包、清理我的解决方案、重建、手动删除所有生成的文件和目录等等。

然后我决定放弃所有的迁移并重新开始,但是接下来发生了奇怪的事情。在删除所有的迁移和数据库中的migrationhistory表之后,我使用CreateDatabaseIfNotExists初始化器重新创建了数据库。然后我应该能够创建一个新的初始迁移。但当我尝试创建新的迁移时,它会显示错误,说有未处理的迁移,并列出了我刚从项目中删除的所有迁移。

我不知道EF为什么还记得那些迁移。

我甚至试图通过搜索文件内容寻找迁移是否被保存在其他地方,但什么也没有找到。

当Scott Hansleman在舞台上演示数据迁移时,看起来非常整洁,但对于真正的工作,我开始寻找替代方案。

项目开始时,我们使用的是EF 4.x,前段时间切换到了5.0,但自从转换以来,我已经成功添加了许多迁移。

有人知道如何解决这个问题吗?基本上,我只想能够添加迁移并生成带有更改的SQL脚本。

17个回答

49

糟糕,我的情况是我正在添加一个新的根实体,没有被任何其他实体引用。结果就是Code First没有生成这个实体的迁移。一旦我将代码添加到DbContext(一个DbSet)中,它就可以正常工作。


3
这也是我的问题。如果新实体没有被带有DbSet<T>的上下文引用,它们似乎不会被捕获。 - jocull
如果您想要在迁移脚本中生成实体,请确保将它们作为DbSet<T>包含在ApplicationDbContext(或您正在使用的任何其他上下文)中。否则,它们将不会被生成。+1 for this. - Steve Woods
另外,如果您正在使用Fluet API,请确保表关系正确。在我的情况下,我有一个可空的FK。该字段在模型中标记为可空,在配置中标记为IsOptional,但我忘记更新多对多关系。 HasOptional(a => a.License).WithMany(b => b.Stores).HasForeignKey(c => c.LicenseId).WillCascadeOnDelete(false);``` - Vector
这里是我,午夜时分,在将新模型放入迁移之前,我要结束今天的工作了,我正在挠头……然后我想……“哦,是啊……添加到dbcontext中”。叹气我得去睡觉了。 - Paul Carlton

47

我有一个类似的问题,即使我尝试了各种方法,update-database 仍然给我以下错误:

Unable to update database to match the current model because there are pending changes and automatic migration is disabled. Either write the pending model changes to a code-based migration or enable automatic migration. Set DbMigrationsConfiguration.AutomaticMigrationsEnabled to true to enable automatic migration.
You can use the Add-Migration command to write the pending model changes to a code-based migration.

进行“批量清理”解决了我的问题,这表明 EF 使用了一个旧的/无效的程序集来自于文件夹,而不是当前选定的“解决方案配置(例如DEBUG)”。

希望这对其他人有所帮助。


这也是我的问题。我不确定您是否有任何关于实际需要清理什么才能解决此问题的信息? - Andrew Edvalson
4
在我使用 VS 的所有年份中,我甚至没有注意到“批量构建”这个功能。我原以为“清理解决方案”可以达到同样的效果,但它却失败了......只有通过“批量构建 > 清理”才能完成。谢谢。 - parliament

22

我遇到了同样的问题,但发现我的新字段作为成员变量添加而不是属性-它缺少{get; set;}部分,这导致迁移跳过该字段。

可能不是您的情况,但它可能会帮助其他人。


这对我有帮助。我忘了 { get; set; },直到我找到这篇帖子才想起来。对我来说是个解决方案,让我解决了问题,重新向前迈进。谢谢。 - undefined

17

我的问题是由以下原因引起的:

  1. 创建迁移(成功)
  2. 决定重新创建它,并删除迁移 .cs 文件
  3. 尝试再次生成它,结果得到空的迁移的 DownUp 函数

在这种情况下,我忘记了删除 ApplicationDbContextModelSnapshot.cs 文件中关于模型更改的条目。 删除此文件中的新映射解决了我的问题,然后它会正确地生成。


2
谢谢!我也忘记在 ApplicationDbContextModelSnapshot.cs 中删除条目,导致新迁移为空。 - Daan
1
@Christian Rondeau,我在哪里可以找到ApplicationDbContextModelSnapshot.cs文件? - JP Dolocanog
@JPDolocanog 它应该在你的项目中,我不记得确切的文件夹,但如果你在源文件中找不到它,那我也不知道了... - Christian Rondeau

10

你的'不同步' - 数据库、迁移、代码 - 会导致各种问题。我已经做了这个(几乎)无数次,效果非常好 - 但你需要稳扎稳打,认真对待你正在做的事情。

你可以阅读一下我写的这个“总结”- 从中间开始看(但也要检查连接)。

Code first create tables

......如果它不起作用,我建议你创建一个小型的“可重复”的场景/模型 - 准确地发布你所拥有的内容。

迁移是如何工作的:

迁移与“迁移表”绑定在一起。

当运行Add-Migration时 - 它会针对“现有数据库”结构和迁移表进行检查 - 并生成“差异”(有时你得到没有“向上”“向下”之类的东西,只是因为两者是同步的)。

因此,每个“迁移”都是你的代码、现有迁移、数据库和迁移表之间的复杂差异。除了删除数据库之外,没有其他方法可确保重置 - 数据库“迁移”表可能不足以保证完全“清理”(如果可能,我总是进行完整的数据库删除)。你还需要删除你的代码迁移。

在相关的情况下,在之前/之后一定要“编译”项目(最好在配置中自动编译)。

确保你的“连接”匹配。

一旦所有内容同步 - 一切应该都能很好地工作 - 但你必须保持同步。除非你计划删除数据库(测试),否则不要随意删除迁移(你可以使用Update-Database -0(我认为是这样)返回到某个迁移(这是“零状态”)。


这个“迁移表”在哪里? - Chuck Savage
@ChuckSavage - 我没有检查最近的版本,但我认为它在系统表下,以“__”为前缀。 - NSGaga-mostly-inactive
这确实是我的问题。我尝试运行一个会导致数据丢失(故意的)的迁移,但被拒绝了。我再次尝试使用-Force标志运行,它工作了,但它创建了一个“自动迁移”,导致了不对齐。删除它解决了我的问题。 - Tu.Ma.

7
我曾经遇到过类似的问题,使用-force标志在add-migration上重新生成现有迁移时,出现了无法生成显式迁移的错误信息。我尝试了几乎所有可能的方法,但仍然无法解决这个问题。最后,我绝望地再次运行了enable-migrations,当然又收到了“迁移已在项目'Blah.Blah'中启用”的消息。然后我再次尝试运行add-migration -force,神奇的是它居然可以工作了。
我不知道它改变了什么,可能是一些用户设置或配置文件不在源代码控制之下。希望这对其他人有所帮助。

是的,兄弟。在运行了 enable-migrations 之后,它神奇地开始工作了。 - André Mendonça

5

批量构建 -> 清除选项对我无效。

我通过以下方式解决了这个问题:

  1. 使用'Add-Migration NameOfMigration'创建迁移。
  2. 删除所创建迁移类的up和down函数的内容。
  3. 通过运行迁移脚本更新数据库(这将只向_MigrationHistory表添加一行数据,使用'Update-Database -Verbose')。

现在Web应用程序已经成功运行,实际上我遇到的问题只需要添加元数据即可解决。


2

这种情况我也遇到过,但是尝试了很多方法都没有解决。后来我自己想了一个办法,现在一切都正常了。

问题: 我创建了一个名为“Cars”的模型,并使用命令“add-migration AddCarModel”为其创建了一个迁移,但是迁移为空。我尝试了不同的名称,还尝试删除迁移的.cs文件,但都没有起作用。接着我做了以下操作:

解决方案: 请按照以下步骤进行操作:

1. 删除您为该模型创建的所有空迁移(但要记住步骤2中迁移的名称)。

2. 同时从“_MigrationHistory”表中删除这些迁移条目。

3. 注释掉您模型DB上下文的代码行(在我的情况下是“public DbSet Cars{ get; set; }”)。

4. 清理并重新构建解决方案。(最好批量清理)

5. 确保您的更新命令正在工作且未抛出错误。(命令:“update-database -verbose”)

6. 现在取消注释步骤3中注释的代码行。

7. 现在为该模型创建迁移。(我使用了与之前相同的名称来创建迁移)

希望能解决您的问题。:-)


1
我向我的数据模型中的子目录添加了一个新类,结果命名空间对使用add-migration的脚手架不可见。
解决方法是将新类的命名空间重命名为与模型的其余部分相符合,和/或将"public virtual DbSet .."等内容添加到实体上下文类中,这将需要您引用此新命名空间,然后再次运行add-migration。

1
我所做的只是在我的ApplicationDbContext类定义中添加了“public DbSet <Vehicle> Vehicles { get; set; }”,然后运行了一个新的迁移,并成功识别了它!感谢Rob。 - SendETHToThisAddress

0
我曾经遇到过同样的问题。虽然启用了迁移,但它们没有检测到任何更改。 我的解决方案是使用-Force属性重新启用迁移,然后一切都正常工作了。

Enable-Migrations -ProjectName -StartupProjectName --ConnectionStringName -Force


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接