2017-03-31 105 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的源代碼文件:

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) 

一對多if塊體:

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

和你做。

+0

我現在工作。謝謝。 –