简体   繁体   English

试图了解在实体框架中删除子实体

[英]Trying to understand deleting children entities in Entity Framework

I'm trying to understand why Entity Framework works the way it does with deleting child entities! 我试图理解为什么实体框架以删除子实体的方式工作!

I have a YogaSpace object/entity and a child entity called YogaSpaceImage . 我有一个YogaSpace对象/实体和一个称为YogaSpaceImage I want to delete a YogaSpaceImage from YogaSpace , so here is what I do. 我想从YogaSpace删除一个YogaSpaceImage ,所以这是我要做的。

This DOES NOT work 不起作用

yogaSpace.Images.Remove(yogaSpaceImage);

to delete a child entity! 删除子实体!

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()
}

This does work when I call myRepo.Removed(YogaSpaceImage) . 当我调用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()
}

Here is what Removed() and InsertOrUpdate() look like in my repo. 这是我的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;
}

PS you would think InsetOrUpdate() in my repo would work for EntityState.Modified to remove a child entity? PS,您会认为我的回购中的InsetOrUpdate()对于EntityState.Modified可以删除子实体吗?

PPS not sure why I even need InsertOrUpdate() , it was built with the auto generated nuget package. PPS不知道为什么我什至需要InsertOrUpdate() ,它是使用自动生成的nuget包构建的。 If I don't use it and just call Save() , Entity Framework understands the changes I've made, so why the heck is it generated for me and why does entity.Added and entity.Modified even exist, because entities get saved and modified even if I don't explicitly calls these two? 如果我不使用它,而只是调用Save() ,那么Entity Framework会理解我所做的更改,因此为什么会为我生成此提示,为什么因为要保存实体,所以entity.Addedentity.Modified甚至存在和修改,即使我没有明确调用这两个?

A nice little trick is to use the parent's id in the child's primary key: 一个不错的小技巧是在孩子的主键中使用父母的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;}
}

And the configuration: 并配置:

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);

This way when you remove a child from the parent, the ParentId cannot be empty and EF will mark the child for deletion. 这样,当您从父级中删除子级时,ParentId不能为空,并且EF会将其标记为要删除。

Example how to add/remove child to parent: 示例如何向父级添加/删除子级:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM