【发布时间】:2016-03-05 19:51:22
【问题描述】:
是否有一种简单的方法可以从包管理器控制台手动运行实体框架迁移 Seed() 方法,包括在 Down() 迁移之后 (Update-Database -TargetMigration foo)? “Run Code First Migration Seed Method without a migration”的答案解决了如何手动运行 Seed() 方法,即调用Update-Database,但是当数据库处于较旧的迁移并且不应更新时,这不起作用。在“How to run Seed() method of Configuration class of migrations”中提出了相同的问题,但它是作为多部分问题的一部分提出的,这部分问题仍未得到解答(尽管整个问题现在都标记为已回答)。
我之所以问,是因为我有一些清理代码需要在应用迁移后运行。从 Seed() 调用它适用于 Up() 迁移。不过,我不知道如何轻松地将其称为 Down() 迁移。我想要一个可以从包管理器中工作的简单的一两个班轮。我知道我可以在为所有必要的 DLL 调用 [Reflection.Assembly]::LoadFile() 之后调用 c# 方法,但是有足够的依赖关系,这会很麻烦且容易出错。
我知道 Seed() 不是 Down() 迁移清理代码的理想位置(根据 DrewJordan 的回答添加一些上下文),但不幸的是,出于多种原因,使用 Down() 本身是不可行的。从实际的角度来看,它是不可行的,因为清理必须转换几 GB 的数据,当我在 Down() 中尝试一个简单的副本时,这导致 SQL Server Express 崩溃,可能是因为生成的事务大小非常大。其次,即使从假设的角度来看,我也不相信有办法将数据转换为 Down() 所需的范围,因为当前 SQL 行无法在 c# 中作为事务的一部分读取,并且数据的转换需要在 c# 中进行。有关该限制的详细信息,请参阅我的另一个问题:“Transform data using c# during Entity Framework migration”。需要对设计进行一些折衷以使清理工作正常进行,我使用 Seed() 作为折衷方案。清理代码本身不需要从 Seed() 运行,但我不知道在不更改当前迁移的情况下还可以从包管理器中调用什么。
还有另一种情况,在不更改当前迁移的情况下单独调用 Seed() 或其他清理代码会很有用。考虑 Seed()/cleanup 方法中存在错误的场景。您修复了该错误并希望在不更改当前迁移的情况下重新运行它。将清理逻辑放在 Down() 中并不能解决问题,因为当数据库已经在迁移时,不会调用 Down()。
【问题讨论】:
-
用Seed方法恐怕无法实现。您可能想要分叉 EntityFramework 并在那里添加迁移拦截,但很可能您只需要考虑另一种实现方式。每次迁移都需要清理大量代码的原因是什么?
-
@raderick 哇——我没有意识到源代码可用于实体框架。谢谢!我将围绕它进行挖掘,看看是否可以找到另一种解决方法。 ...清理是针对一个特定的迁移,似乎没有办法在 Up()/Down() 中进行转换,因为转换是在 c# 中完成的。数据集是巨大的。
-
是否可以通过将此迁移代码添加为单元测试并使用 [Ignore] 属性对其进行标记并手动运行来实现您的目标?
-
@raderick 单元测试听起来也可以,谢谢。顺便说一下,我确实从包管理器控制台中弄清楚了如何做到这一点 - 我在下面发布了我的方法:stackoverflow.com/a/35873514/1552934
-
我看到了你的帖子,但遗憾的是,这种类型的代码可能会产生奇怪的副作用 - 可能性很小,但是,当我面对这样的代码并且没有与那个代码联系时,我个人并不觉得安全谁写的。
标签: c# entity-framework