无法使用代码优先迁移创建ON D​​ELETE SET NULL约束

时间:2014-08-15 22:25:16

标签: sql-server entity-framework ef-migrations

到目前为止,我们为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方法中的之前执行,尽管它是物理上最后一个代码。

那么,这里发生了什么?

1 个答案:

答案 0 :(得分:0)

  

另一个原因可能是约束事实上还不存在。这意味着SQL方法在Up方法中的其他代码之前执行,尽管它在物理上是最后一个代码。

似乎这个假设是正确的:似乎Up方法中定义的操作不是自上而下执行的。

如果我使用Add-Migration创建一个空迁移,并在那里使用SQL方法,那就可以了。