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.
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);
}
}
'Development Tip' 카테고리의 다른 글
* .tar.gz가 여전히 * .tar.xz보다 훨씬 더 일반적인 이유는 무엇입니까? (0) | 2020.11.29 |
---|---|
iOS에서 기본 Twitter 앱을 사용하여 Twitter 트윗을 열려면 어떻게해야합니까? (0) | 2020.11.29 |
Homebrew postgres 깨진 (0) | 2020.11.29 |
'XXX.Global'유형을로드 할 수 없습니다. (0) | 2020.11.29 |
UIScrollView는 예상대로 작동하지만 scrollRectToVisible : 아무것도하지 않습니다. (0) | 2020.11.29 |