到目前为止,我们为EF Code First Context使用了一个简单的DbInitializer类:
Friend Class DbInitializer
Inherit DropCreateDatabaseIfModelChanges(Of MyContext)
Public Overrides Sub InitializeDatabase(context As MyContext)
MyBase.InitializeDatabase(context)
End Sub
Protected Overrides Sub Seed(context as MyContext)
context.Database.ExecuteSql("ALTER TABLE [dbo].[Competitions]" & _
" DROP CONSTRAINT
[FK_dbo.Competitions_dbo.CompetitorLists_PreferredPairsListId]")
context.Database.ExecuteSql("ALTER TABLE dbo.Competitions" & _
" ADD CONSTRAINT [FK_dbo.Competitions_dbo.CompetitorLists_PreferredPlayersListId]" & _
" FOREIGN KEY ([PreferredPlayersListId])" & _
" REFERENCES [dbo].[CompetitorLists] ([ID])" & _
" ON UPDATE NO ACTION ON DELETE SET NULL")
End Sub
Seed
方法为外键创建了一个ON DELETE SET NULL
约束的外键。
现在我们正在迁移到Code First Migrations并更改DbInitializer
因此:
Friend Class DbInitializer
Inherits MigrateDatabaseToLatestVersion(Of MyContext, Migrations.Configuration)
<TraceAspect>
Public Overrides Sub InitializeDatabase(context As MyContext)
MyBase.InitializeDatabase(context)
End Sub
End Class
MigrateDatabaseToLatestVersion
类没有Seed
方法,因此我正在寻找放置ALTER DATABASE
SQL命令的位置。第一次迁移的UP
方法似乎是合乎逻辑的。因此,我将context.Database.ExecuteSQLCommand
更改为用于迁移的较短SQL()
方法:
下面的代码粘贴在第一个被调用的Up
方法的末尾。
Sql("ALTER TABLE [dbo].[Competitions]" & _
" DROP CONSTRAINT [FK_dbo.Competitions_dbo.CompetitorLists_PreferredPairsListId]")
Sql("ALTER TABLE dbo.Competitions" & _
" ADD CONSTRAINT [FK_dbo.Competitions_dbo.CompetitorLists_PreferredPlayersListId]" & _
" FOREIGN KEY ([PreferredPlayersListId])" & _
" REFERENCES [dbo].[CompetitorLists] ([ID])" & _
" ON UPDATE NO ACTION ON DELETE SET NULL")
但没有运气:当我在调试器中标记行时代码被传递,但在Up
方法结束后我得到一个Exception声明
FK_dbo.Competitions_dbo.CompetitorLists_PreferredPlayersListId不是约束。无法删除约束。查看以前的错误。
之前的错误没有...
请注意,异常不是 on SQL方法,而是稍后。
我搜索了这个,我可以找到的原因之一是实体框架更改了版本之间的命名约定。这不是问题所在:我检查了当我省略droppinge并添加约束时,它是由EF创建的同名。
另一个原因可能是约束事实上还不存在。这意味着SQL
方法在Up
方法中的之前执行,尽管它是物理上最后一个代码。
那么,这里发生了什么?
答案 0 :(得分:0)
另一个原因可能是约束事实上还不存在。这意味着SQL方法在Up方法中的其他代码之前执行,尽管它在物理上是最后一个代码。
似乎这个假设是正确的:似乎Up
方法中定义的操作不是自上而下执行的。
如果我使用Add-Migration创建一个空迁移,并在那里使用SQL
方法,那就可以了。