2016-08-16 5 views
1

다음 개체가 EF에 정의되어 있습니다.Entity Framework 자식 레코드 식별 및 삭제

public class ItemA() 
{ 
     public virtual ICollection<ItemB> Items{ get; set; } 
} 

public class ItemB() 
{ 
     public virtual ICollection<ItemC> Items{ get; set; } 
} 

제 코드에서는 다음을 수행하고 있습니다. ItemA의 인스턴스가 채워집니다

myItemA.Items.Remove(myItemA.Items.FirstOrDefault(x => (int)x.Type == model.Type)); 

myItemA.Items.Add(new ItemB()); 

, 그것은 하나의 ItemB를 포함하고 나는 단순히 ItemB의 새 인스턴스와 이것을 대체 할. 내 서비스로 메시지를 업데이트하면 다음 코드를 호출하면 새 ItemB가 생성되고 기존 ItemB는 부모 ID가 null 인 고아가됩니다. ItemB와 ItemC 사이의 링크는 손상되지 않습니다.

_dbContext.Entry(entity).State = EntityState.Modified; 
_dbContext.SaveChanges(); 

그래서, 나는 희망 캐스케이드 아이 ItemC 기록하고 고아 ItemB 삭제됩니다이다 ItemB 아이가 삭제 될 EF와 모델의 제약 조건 설정을 알려줄 필요가 있음을 알고있다. 그러나 나는 그렇게하는 방법을 찾기 위해 고심하고있다.

부모 항목을 컨텍스트에서 다시 가져 와서 목록을 비교하고 삭제 된 것으로 표시하려고 시도했지만 프록시를 다시 가져 오는 동안 두 개체가 본질적으로 동일하며 업데이트 된 ItemB 만 있고 그렇지 않습니다. 실물.

var existing Items = GetItem(entity.Id).Items.ToList(); 

var existingItem = GetItem(entity.Id); 

또는

그래서 내가 필요한 원래 ItemA.Items들이 삭제 될 수 있습니다 EF을 말할 수있을 것입니다. EF에 무엇인가가 삭제되어야한다고 말하는 방법을 알고 있습니다. 나는 삭제되어야하는 엔티티에 대한 참조를 얻는 것에 만 관심이 있습니다.

편집

이 코드를 추가하면 그러나, 지금까지의 내가 그것을 이해이 지금이 거래 범위 내에서 실시 할 것, 그것이 작동하게하고 (아이 ItemC와) 분리 된 ItemB은 이제 제거됩니다.

//Update Message 
    _dbContext.Entry(entity).State = EntityState.Modified; 
    _dbContext.SaveChanges(); 

    //Remove any orphaned records 
    var itemsToRemove = _dbContext.Set<ItemB>().Where(x => x.ItemA == null).ToList(); 
    _dbContext.Set<ItemB>().RemoveRange(itemsToRemove); 
    _dbContext.SaveChanges(); 

이상적 방법을 찾고해야 할 일이 하나의 SaveChanges()

+0

엔터티 상태를 삭제하려고 시도 했습니까? 'foreach (item.Items의 var 자식 항목) dbContext.Entry (childItem) .State = EntityState.Deleted;'? –

+0

이것은 문제입니다. item.Items에는 삭제하려는 항목이 포함되어 있지 않으며, 새 itemB 만 포함되어 추가됩니다. 원래 ItemB는 고아가됩니다. – ChrisBint

+0

제거하고 다시 추가하기 전에 의미합니다. 하지만 다음 줄을 사용하여 제거하려는 것은 무엇입니까? item.Items.Remove (item.Items.FirstOrDefault (x => (int) x.Type == model.Type));'항목을 어디에서 구합니까? 데이터베이스에서? –

답변

0

음 .. 내가 뭔가를 잘못 이해하거나 당신은 단지 폭포는 다음과 같이 삭제 구현하고자 했는가 :

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<ItemB>().HasRequired(b => b.Parent).WithMany(a => a.Items).WillCascadeOnDelete(); 
} 

이것은 또한 작동합니다 :

public class ItemA() 
{ 
    public virtual ICollection<ItemB> Items{ get; set; } 
} 

public class ItemB() 
{ 
    [Required] // This set's the constraint 
    public virtual ItemA Parent { get; set; } 
    public virtual ICollection<ItemC> Items{ get; set; } 
} 

Did't 두 번째 하나를 사용하지만, 그러나 그것은해야 동일한 결과를 가져라.