试图了解在Entity Framework中删除子实体

时间:2016-03-26 01:04:15

标签: c# entity-framework

我试图理解为什么实体框架的工作方式与删除子实体的方式相同!

我有一个YogaSpace对象/实体和一个名为YogaSpaceImage的子实体。我想从YogaSpaceImage删除YogaSpace,所以这就是我所做的。

工作

yogaSpace.Images.Remove(yogaSpaceImage);

删除子实体!

public string RemoveImage(int id, int imageIdToDelete)
{
        YogaSpace yogaSpace = _yogaSpaceRepository.Find(id);

        // delete image
        foreach (YogaSpaceImage yogaSpaceImage in yogaSpace.Images.OrderBy(m => m.Ordering))
        {
            if (yogaSpaceImage.YogaSpaceImageId == imageIdToDelete)
            {
                // check first to see if the deleted image is the first (primary) image, then make the 2nd image the yogaspace thumbnail
                if (yogaSpaceImage.Ordering == 1)
                {
                    yogaSpace.SpaceThumbnail = yogaSpace.Images.First(m => m.Ordering == 2).ImageThumbnail;
                }
                yogaSpace.Images.Remove(yogaSpaceImage);
            }
        } 
     }

     myRepository.InsertOrUpdate(YogaSpace);
     myRepository.Save()
}

当我致电myRepo.Removed(YogaSpaceImage)时, 会有效。

public string RemoveImage(int id, int imageIdToDelete)
{
        YogaSpace yogaSpace = _yogaSpaceRepository.Find(id);

        // delete image
        foreach (YogaSpaceImage yogaSpaceImage in yogaSpace.Images.OrderBy(m => m.Ordering))
        {
            if (yogaSpaceImage.YogaSpaceImageId == imageIdToDelete)
            {
                // check first to see if the deleted image is the first (primary) image, then make the 2nd image the yogaspace thumbnail
                if (yogaSpaceImage.Ordering == 1)
                {
                    yogaSpace.SpaceThumbnail = yogaSpace.Images.First(m => m.Ordering == 2).ImageThumbnail;
                }

                _yogaSpaceRepository.Removed(yogaSpaceImage);  
            }
        } 
     }

     myRepository.Save()
}

以下是我的回购邮件中Removed()InsertOrUpdate()的样子。

public void InsertOrUpdate(YogaSpace yogaSpace)
{
        if (yogaSpace.YogaSpaceId == default(int))
        {
            context.Entry(yogaSpace).State = System.Data.Entity.EntityState.Added;
        }
        else
        {
            context.Entry(yogaSpace).State = System.Data.Entity.EntityState.Modified;
        }
}

public void Removed(YogaSpaceImage yogaSpaceImage)
{
        context.Entry(yogaSpaceImage).State = EntityState.Deleted;
}

P.S。您认为我的仓库中的InsetOrUpdate()可以用于EntityState.Modified删除子实体吗?

P.P.S。不知道为什么我甚至需要InsertOrUpdate(),它是使用自动生成的nuget包构建的。如果我不使用它并且只是致电Save(),则实体框架会理解我所做的更改,那么为什么会为我生成这些更改以及为什么entity.Added和{{{{}} 1}}甚至存在,因为即使我没有明确地调用这两个实体,实体也会被保存和修改?

1 个答案:

答案 0 :(得分:2)

一个不错的小技巧是在孩子的主键中使用父母的id:

public class Parent
{
    public int Id { get; set; }

    public virtual List<Child> Children { get; set; }
}

public class Child
{
    public int Id { get; set; }

    public int ParentId { get; set;}
}

配置:

modelBuilder.Entity<Parent>()
            .HasMany(x => x.Children)
            .WithRequired()
            .HasForeignKey(x => x.ParentId);

modelBuilder.Entity<Child>()
            .HasKey(x => new { x.Id, x.ParentId})
            .Property(x => x.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

这样,当您从父级移除子级时,ParentId不能为空,EF会将该子级标记为删除。

如何添加/删除子项到父项的示例:

using(var db = new DbContext())
{
    var p = db.Parents.First();
    var c = new Child();
    p.Children.Add(c);
    db.SaveChanges(); // Child was saved to the database

    p.Children.Remove(c);
    db.SaveChanges(); // Child will be deleted from the database

    p.Children.Clear();
    db.SaveChanges(); // All Child of this parent will be deleted
}