Development Tip

EF 코드 첫 번째 데이터베이스에서 자식 일대 다 관련 레코드를 제거하는 방법은 무엇입니까?

yourdevel 2020. 11. 29. 12:20
반응형

EF 코드 첫 번째 데이터베이스에서 자식 일대 다 관련 레코드를 제거하는 방법은 무엇입니까?


음, 일대 다 관련 모델이 있습니다.

public class Parent
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Child> Children { get; set; }
}

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

내가 원하는 것은 Parent.Children데이터베이스에서 관련 하위 엔티티를 지우고 제거하는 것입니다. 나는 이미 시도했다 :

데이터베이스 컨텍스트 클래스 :

modelBuilder.Entity<Parent>()
            .HasMany(p => p.Children)
            .WithOptional()
            .WillCascadeOnDelete(true);

이것은 잘 작동하지만 Parent_Id = null할 때 필드가 있는 데이터베이스에 중복 레코드 가 있습니다.

parent.Children.Clear();
repository.InsertOrUpdate(parent);

내 저장소 클래스에서. 또한 동일한 동작은 다음과 같습니다.

modelBuilder.Entity<Parent>()
            .HasMany(pr => pr.Children)
            .WithOptional(ri => ri.Parent)
            .WillCascadeOnDelete(true);

클래스의 추가 Parent속성Child

public class Child
{
    ...
    public Parent Parent { get; set; }
    ...
}

또는 내가 할 때

modelBuilder.Entity<Child>()
            .HasOptional(p => p.Parent)
            .WithMany(p => p.Children)
            .HasForeignKey(p => p.Parent_Id)
            .WillCascadeOnDelete(true);

Child클래스에 추가 Parent_Id 속성 포함

public class Child
{
     ...
     public int Parent_Id { get; set; }
     ...
}

그렇다면 계단식 삭제를 올바르게 구성하려면 어떻게해야합니까? 또는 해당 하위 엔티티를 어떻게 제거해야합니까? 나는 이것이 평범한 일이라고 생각하지만 나는 단지 무언가를 놓치고 있습니다.


Cascading delete has no effect here because you don't delete the parent but just call InsertOrUpdate. The correct procedure is to delete the children one-by-one, like so for example:

using (var context = new MyContext())
{
    var parent = context.Parents.Include(p => p.Children)
        .SingleOrDefault(p => p.Id == parentId);

    foreach (var child in parent.Children.ToList())
        context.Children.Remove(child);

    context.SaveChanges();
}

In EF6 a faster way to do the operation is...

 context.Children.RemoveRange(parent.Children)

This is called "deleting orphans".

Can EF automatically delete data that is orphaned, where the parent is not deleted?

I don't know how it works in EF6 but in EF Core it works fine https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete so you don't necessarily need to delete the parent for cascades to work.

Delete orphans examples


Try changing to

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

because virtual is needed to get lazy loading. as explained here

I think your parent.Children.clear isnt working because the Children have not been loaded


If your object is self-referencing, you can delete both many-to-many and one-to-many children using the method below. Just remember to call db.SaveChanges() afterwards :)

[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
    Object obj = this.db.Objects.Find(id);
    this.DeleteObjectAndChildren(obj);
    this.db.Objects.Remove(obj);
    this.db.SaveChanges();
    return this.Json(new { success = true });
}

/// <summary>
/// This deletes an object and all children, but does not commit changes to the db.
///  - MH @ 2016/08/15 14:42
/// </summary>
/// <param name="parent">
/// The object.
/// </param>
private void DeleteObjectAndChildren(Object parent)
{
    // Deletes One-to-Many Children
    if (parent.Things != null && parent.Things.Count > 0)
    {
        this.db.Things.RemoveRange(parent.Things);
    }

    // Deletes Self Referenced Children
    if (parent.Children != null && parent.Children.Count > 0)
    {
        foreach (var child in parent.Children)
        {
            this.DeleteObjectAndChildren(child);
        }

        this.db.Objects.RemoveRange(parent.Children);
    }
}

참고URL : https://stackoverflow.com/questions/16654828/how-to-remove-child-one-to-many-related-records-in-ef-code-first-database

반응형