Sql server 首先在EF核心代码中将DeleteBehavior从Cascade更改为Restrict

Sql server 首先在EF核心代码中将DeleteBehavior从Cascade更改为Restrict,sql-server,entity-framework,asp.net-core,migration,ef-code-first,Sql Server,Entity Framework,Asp.net Core,Migration,Ef Code First,我正在尝试将删除行为从级联更改为限制 我正在使用EF core进行迁移 这就是使用级联删除行为进行迁移的方式 migrationBuilder.CreateTable( name: "ElementsPerStrip", columns: table => new { ...... }, constraints: tab

我正在尝试将
删除行为
级联
更改为
限制
我正在使用EF core进行迁移

这就是使用级联删除行为进行迁移的方式

migrationBuilder.CreateTable(
            name: "ElementsPerStrip",
            columns: table => new
            {
                ......
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_ElementsPerStrip", x => x.Id);
                table.ForeignKey(
                    name: "FK_ElementsPerStrip_Strips_StripId",
                    column: x => x.StripId,
                    principalTable: "Strips",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
            });
在此之后进行了一些迁移,现在我需要将
referentialition
还原为
Restrict

以下是我的条形模型的外观:

public class Strip
{
    public int Id { get; set; }
    public int ProjectId { get; set; }
    public int ScriptId { get; set; }
    public virtual Script Script { get; set; }
    public int SceneId { get; set; }        
    ...
    public virtual ICollection<ElementPerStrip> ElementPerStrip { get; set; }
}
在modelbuilder中,我添加了此选项,试图将Deletebehavior更改为限制:

builder.Entity<Strip>()
        .HasMany(c => c.ElementPerStrip)
        .WithOne()
        .HasForeignKey(c => c.StripId)
        .OnDelete(DeleteBehavior.Restrict);
但当我运行应用程序并尝试删除条带时,会出现以下错误:

The DELETE statement conflicted with the REFERENCE constraint "FK_ElementsPerStrip_Strips_StripId". The conflict occurred in database "MDb", table "dbo.ElementsPerStrip", column 'StripId'.
我无法删除StripId列,因为我需要用于应用程序中筛选目的的数据。
如何解决断开两个表的连接但保留数据但更改删除行为的问题。

SQL Server 2005及更高版本中有四个可用选项,如下所示:

  • 不采取行动
  • 级联
  • 设置空值
  • 设置默认值
以下是更新和删除操作的效果摘要:

向外键添加约束的步骤

打开新查询窗口

[SQL]添加
约束

ALTER TABLE [dbo].[ToDoItem]
   ADD CONSTRAINT FK_Delete_NoAction
   FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([Id]) ON DELETE No Action ON UPDATE No Action
单击绿色箭头执行。

无操作设置的结果


当您切换回**级联**模式时
ALTER TABLE [dbo].[ToDoItem]
   DROP CONSTRAINT [FK_Delete_NoAction]

ALTER TABLE [dbo].[ToDoItem]
   ADD CONSTRAINT FK_Delete_Cascade
   FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([Id]) ON DELETE Cascade ON UPDATE Cascade
删除用户时将删除ToDoItem




如果数据库使用的是SQL Server Management Studio(SSMS),则会更简单

→ 右键单击表设计并转到关系,在左侧窗格中选择外键,在右侧窗格中,展开菜单“插入和更新规范”,并选择“限制”作为删除规则


要使用EF迁移更改删除行为,必须删除并重新创建外键

在Package Manager控制台中,使用
Add migration
命令创建一个新的空迁移,然后像这样填写
Up
方法:

        migrationBuilder.DropForeignKey(
            name: "FK_ElementsPerStrip_Strips_StripId",
            table: "ElementsPerStrip");
        migrationBuilder.AddForeignKey(
            name: "FK_ElementsPerStrip_Strips_StripId",
            table: "ElementsPerStrip",
            column: "StripId",
            principalTable: "Strips",
            principalColumn: "Id",
            onDelete: ReferentialAction.Restrict);
为完整起见,请在
向下
方法中执行相反的操作:

        migrationBuilder.DropForeignKey(
            name: "FK_ElementsPerStrip_Strips_StripId",
            table: "ElementsPerStrip");
        migrationBuilder.AddForeignKey(
            name: "FK_ElementsPerStrip_Strips_StripId",
            table: "ElementsPerStrip",
            column: "StripId",
            principalTable: "Strips",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);

请注意:忽略任何通过SSM修改DB模式的建议。当您这样做的时候,您就破坏了迁移策略,其要点是通过构建/部署管道让您控制模式,并始终使模式与代码保持一致。

Phil要求提供代码优先的解决方案。这不是代码优先。
        migrationBuilder.DropForeignKey(
            name: "FK_ElementsPerStrip_Strips_StripId",
            table: "ElementsPerStrip");
        migrationBuilder.AddForeignKey(
            name: "FK_ElementsPerStrip_Strips_StripId",
            table: "ElementsPerStrip",
            column: "StripId",
            principalTable: "Strips",
            principalColumn: "Id",
            onDelete: ReferentialAction.Restrict);
        migrationBuilder.DropForeignKey(
            name: "FK_ElementsPerStrip_Strips_StripId",
            table: "ElementsPerStrip");
        migrationBuilder.AddForeignKey(
            name: "FK_ElementsPerStrip_Strips_StripId",
            table: "ElementsPerStrip",
            column: "StripId",
            principalTable: "Strips",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);