2017-03-31 15 views
1

엔터티 프레임 워크에서 내 개체를 재귀 적으로 분리하는 방법을 작성했습니다. 실제로 작동하지만 문제는이 메서드를 실행 한 후 일대 다 속성 (개체 컬렉션)이 제거된다는 것입니다. 내 코드 아래 :엔터티 프레임 워크에서 재귀 엔터티 분리

public void DetachRec(object objectToDetach) 
{ 
    DetachRec(objectToDetach, new HashSet<object>()); 
} 

// context is my ObjectContext 
private void DetachRec(object objectToDetach, HashSet<object> visitedObjects) 
{ 
    visitedObjects.Add(objectToDetach); 

    if (objectToDetach == null) 
    { 
    return; 
    } 
    Type type = objectToDetach.GetType(); 
    PropertyInfo[] propertyInfos = type.GetProperties(); 
    foreach (PropertyInfo propertyInfo in propertyInfos) 
    { 
    // on to many 
    if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>)) 
    { 

     if (context.Entry(objectToDetach).Collection(propertyInfo.Name).IsLoaded) 
     { 

     var propValue = (IEnumerable) propertyInfo.GetValue(objectToDetach, null); 

     if (propValue != null) 
     { 
      var subcontext = new List<object>(); 

      foreach (var subObject in propValue) 
      { 
      subcontext.Add(subObject); 
      } 
      foreach (var subObject in subcontext) 
      { 
      if (!visitedObjects.Contains(subObject)) 
      { 
       context.DetachRecursive(subObject, visitedObjects); 
      } 
      } 
     } 
     } 
    } 
    // (many to one) 
    else if (propertyInfo.PropertyType.Assembly == type.Assembly) 
    { 
     //the part to detach many-to-one objects 
    } 
    } 

    context.Detach(objectToDetach); 
} 
+0

"컬렉션이 제거되었습니다"라고 말하면 그게 무슨 뜻입니까? 그 속성이 null을 반환한다는 것을 의미합니까? – JuanR

+1

http://stackoverflow.com/a/7693732/430661을 읽고 적용되는지 확인하십시오. –

+0

@Juan, 예, 속성은 null을 반환합니다. –

답변

3

콜렉션 요소를 분리하기 전에 컬렉션의 값을 저장할 수 있고 null에 컬렉션 속성을 설정합니다. 이 방법을 사용하면 요소 및/또는 상위 항목을 분리 할 때 EF가 콜렉션 요소를 제거하는 것을 방지 할 수 있습니다. 프로세스가 끝나면 해당 값을 복원하기 만하면됩니다. 다음과 같이

using System.Data.Entity.Infrastructure; 

변경 대중 메소드 구현 :

public void DetachRec(object objectToDetach) 
{ 
    var visitedObjects = new HashSet<object>(); 
    var collectionsToRestore = new List<Tuple<DbCollectionEntry, object>>(); 
    DetachRec(objectToDetach, visitedObjects, collectionsToRestore); 
    foreach (var item in collectionsToRestore) 
     item.Item1.CurrentValue = item.Item2; 
} 

민간 재귀 메소드 서명에 :

private void DetachRec(object objectToDetach, HashSet<object> visitedObjects, List<DbCollectionEntry, object>> collectionsToRestore) 
소스 코드 파일에 다음 using를 추가하여

시작

대다수

var collectionEntry = context.Entry(objectToDetach).Collection(propertyInfo.Name); 
if (collectionEntry.IsLoaded) 
{ 
    var collection = collectionEntry.CurrentValue; 
    if (collection != null) 
    { 
     collectionsToRestore.Add(Tuple.Create(collectionEntry, collection)); 
     collectionEntry.CurrentValue = null; 
     foreach (var item in (IEnumerable)collection) 
     { 
      if (!visitedObjects.Contains(item)) 
      { 
       DetachRec(item, visitedObjects, collectionsToRestore); 
      } 
     } 
    } 
} 

하면 모든 작업이 완료됩니다if 블록 몸에.

+0

지금 일합니다. 감사. –