如何在EF Code First中删除零个或一个外键关系?删除可选实体时,在表中删除FK

时间:2014-09-03 09:58:19

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

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

  

“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定义,没有改变这种情况。 这些定义有什么问题?

谢谢。

2 个答案:

答案 0 :(得分:0)

在调用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)。 我个人更喜欢控制我正在做的事情......

答案 1 :(得分:0)

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

创建了一个"动作过滤器属性"在相关控制器的删除操作之前执行。该过滤器从其他表/存储库中删除to-be-deleted-object的ID,然后返回实际的Delete操作。

因为在删除实际对象之前删除了所有外键,所以不会出现问题。