如何删除EF Code First中从另一个实体引用的实体?

时间:2011-11-03 19:30:15

标签: asp.net-mvc entity-framework ef-code-first entity-framework-4.1

晚安。我有以下关系问题。 我有一个图片类Imagem

public class Imagem : Entity
{
    public long Id {get ; set;}

    public string Name{ get; set; }
}

我正在建立一种画廊,我在gallery的前页上有一张图片。

public class gallery: Entity
{
    public long Id {get ; set;}

    public Imagem Frontsheet{ get; set; }
}

我最大的问题是当我删除图像时它不会离开,因为 图像与图库相关联。

如何处理此类情况,以便从图像表中删除图像?

2 个答案:

答案 0 :(得分:0)

您在数据库中有一个约束,如果任何图库通过FrontSheet属性引用该图像,则禁止删除该图像。您需要做的是将这些关系设置为NULL。 (该关系似乎是可选的,因此您可以将数据库中的外键设置为NULL。)对于您的模型,您必须选择所有引用您想要删除的图像的库。如果您要删除ID为givenImageId的图片

,它将如下所示
using (var context = new MyDbContext())
{
    var imageToDelete = context.Images.Single(i => i.Id == givenImageId);
    var galleries = context.Galleries.Include("Frontsheet")
        .Where(g => g.Frontsheet.Id == givenImageId)
        .ToList();

    foreach(var gallery in galleries)
        gallery.Frontsheet = null;

    context.Images.Remove(imageToDelete);

    context.SaveChanges();
}

如果您的Gallery实体上有外键属性...

public long? FrontsheetId { get; set; }

...您不需要将frontsheets与画廊一起加载,从而提高性能:

using (var context = new MyDbContext())
{
    var imageToDelete = context.Images.Single(i => i.Id == givenImageId);
    var galleries = context.Galleries  // no Include anymore required
        .Where(g => g.FrontsheetId == givenImageId)
        .ToList();

    foreach(var gallery in galleries)
        gallery.FrontsheetId = null;

    context.Images.Remove(imageToDelete);

    context.SaveChanges();
}

答案 1 :(得分:0)

我不确定实体之间的关系究竟是什么,但看起来它是1:1的关系。您需要配置关系以级联删除:

modelBuilder.Entity<gallery>().HasOptional(g => g.Image).WithRequired().WillCascadeOnDelete();

在上下文中的实体配置中执行此操作:

public class SomeContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Entity<gallery>().HasOptional(g => g.Image).WithRequired().WillCascadeOnDelete();
    }
}

这假设是可选/必需的关系。您也可以执行必需/必需的操作。它还假设您没有从图像到图库的导航属性。

如果您发布两个模型的完整代码,那么帮助您将会容易得多。

如果您不希望数据库级联删除,则可以在删除图库之前删除图像。