【问题标题】:How to delete a zero or one foreign key relation in EF Code First? FK to be deleted in tables when optional entity deleted如何在 EF Code First 中删除零或一个外键关系?删除可选实体时要在表中删除 FK
【发布时间】:2014-10-27 18:46:39
【问题描述】:

我有两个类,其中一个拥有其他的可空 ID 属性(作为外键)和虚拟导航属性。 当我删除我的实体时,我希望从作为外键保存的其他表中删除它的 ID。它没有发生,我得到错误:

"DELETE 语句与 REFERENCE 约束冲突 FK_MyDb.ArtWorks_MyDb.ImageFiles_ImgId。冲突 发生在数据库 MyDatabase ,表 MyDb.ArtWorks 中, “ImgId”列。声明已终止。”

这是持有外键的实体:

public class ArtWork : EntityBase
{
 public int ID { get; set; }
 public int? ImgId { get; set; }
 public virtual ImageFile Img { get; set; }
}

这是我删除错误时发生的实体。

public class ImageFile
{
    public int ID { get; set; }
}

据我所见,迁移文件已正确创建:

            CreateTable(
            "MyDb.ArtWorks",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true),
                    ImgId = c.Int()
                })
            .PrimaryKey(t => t.ID)
            .ForeignKey("MyDb.ImageFiles", t => t.ImgId)
            .Index(t => t.ImgId);

另一个:

            CreateTable(
            "MyDb.ImageFiles",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true)
                })
            .PrimaryKey(t => t.ID);

为了简短起见,我已经删除了这里不相关的属性。

我尝试了几个流畅的 api 定义,没有一个改变这种情况。 这些定义有什么问题?

谢谢。

【问题讨论】:

    标签: c# entity-framework ef-code-first entity-framework-6


    【解决方案1】:

    在调用 Db.ImageFiles.Remove(myImageFile) 之前, 你应该删除依赖它的艺术品:

    ImageFile.Artworks.Clear();//If you have this relation
    //Otherwise
    foreach (var artwork in Db.Artworks.Where(x=>x.ImgId == myImageFile.ID)){
         artwork.ImgId = null;
    }
    

    另一种解决方案是要求 EF 级联删除。 如果您愿意,可以查看这篇文章 (StackOverflow : Entity Framework (EF) Code First Cascade Delete)。 我个人更喜欢控制我正在做的事情......

    【讨论】:

    • 要使用您链接的其他 Stackoverflow 问题中提出的方法,我不能将外键声明为可为空的 int。我想这样声明它们。当一个表中的一行被删除时,应该有一个自动传播,在其他表中作为 FK 包含的 ID 也被删除。
    • 您实际上可以将外键声明为可为空的...看看这个可能吗? stackoverflow.com/questions/5668801/…
    • 我知道你可以,看看我的例子,就是这样。但是,当您执行 .HasOptional() 和 .WithOptionalDependent() 之类的流畅 API 声明时,就会出现错误。对于 fluent API,它们不应为空。
    【解决方案2】:

    这就是我解决这种情况的方法,但我不喜欢它:

    创建了一个“动作过滤器属性”,在相关控制器的删除动作之前执行。该过滤器从其他表/存储库中删除待删除对象的 ID,然后返回到实际的删除操作。

    因为在实际删除对象之前所有外键都被删除了,所以没有问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-28
      • 2014-09-26
      相关资源
      最近更新 更多