2015-09-15 36 views
0

保存數據庫上下文時,存在以下異常:由於一個或多個外鍵屬性不可空,因此無法更改關係。實體框架,在沒有父母的情況下獲取孤兒子記錄/記錄

如上所述here,這可能是由於缺少級聯刪除。 但是,這不是我的代碼,我不知道哪個表可以包含孤兒記錄。錯誤信息並不這樣說。

有沒有辦法檢索這些孤兒記錄。 (至少知道它們在哪個表中)

然後,我將能夠確定需要調整哪部分代碼。

+0

這個問題是類似的,沒有答案。 http://stackoverflow.com/q/3037761/4625305 – AXMIM

回答

0

在實體框架中,當你有多對多的關係時,並且你試圖從像parent.Children.Remove(child)這樣的對象中刪除時,這隻會將該子對象從中間連接表中分離出來。所以你必須找到孩子並從DbContext ChildrenToParent實體中移除它,例如DbContext.ChildrenToParent.Remove(child)。如果你給出一些代碼示例和/或數據庫圖,我想我可以更精確地解釋它。

+0

該數據庫似乎沒有多對多的關係。只有一對多。我的問題更多的是如何找到錯誤表,然後如何解決它,因爲我非常肯定,一旦我知道哪個表具有錯誤數據,我將能夠修復錯誤。 – AXMIM

+0

找到它是手動的。現在我知道你在哪裏試圖解釋。忘記多對多,它也會發生在一對多的情況下。另外,較短的答案就是記錄必須從上下文中刪除,而不是從擁有它的parentEntity中刪除它。 – AXMIM

+0

是的,對於其他問題,您可以嘗試查找Entity Profiler,它顯示查詢是在數據庫中生成的,或者LinqPad也是一個很好的工具。 –

0

您可以嘗試以下解決方案嗎?必須在DetectChanges和SaveChanges方法之間調用DeleteOrphans擴展方法。

public static class DbContextExtensions 
{ 
    private static readonly ConcurrentDictionary< EntityType, ReadOnlyDictionary< string, NavigationProperty>> s_navPropMappings = new ConcurrentDictionary< EntityType, ReadOnlyDictionary< string, NavigationProperty>>(); 

    public static void DeleteOrphans(this DbContext source) 
    { 
     var context = ((IObjectContextAdapter)source).ObjectContext; 
     foreach (var entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified)) 
     { 
      var entityType = entry.EntitySet.ElementType as EntityType; 
      if (entityType == null) 
       continue; 

      var navPropMap = s_navPropMappings.GetOrAdd(entityType, CreateNavigationPropertyMap); 
      var props = entry.GetModifiedProperties().ToArray(); 
      foreach (var prop in props) 
      { 
       NavigationProperty navProp; 
       if (!navPropMap.TryGetValue(prop, out navProp)) 
        continue; 

       var related = entry.RelationshipManager.GetRelatedEnd(navProp.RelationshipType.FullName, navProp.ToEndMember.Name); 
       var enumerator = related.GetEnumerator(); 
       if (enumerator.MoveNext() && enumerator.Current != null) 
        continue; 

       entry.Delete(); 
       break; 
      } 
     } 
    } 

    private static ReadOnlyDictionary<string, NavigationProperty> CreateNavigationPropertyMap(EntityType type) 
    { 
     var result = type.NavigationProperties 
      .Where(v => v.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many) 
      .Where(v => v.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One || (v.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.ZeroOrOne && v.FromEndMember.GetEntityType() == v.ToEndMember.GetEntityType())) 
      .Select(v => new { NavigationProperty = v, DependentProperties = v.GetDependentProperties().Take(2).ToArray() }) 
      .Where(v => v.DependentProperties.Length == 1) 
      .ToDictionary(v => v.DependentProperties[0].Name, v => v.NavigationProperty); 

     return new ReadOnlyDictionary<string, NavigationProperty>(result); 
    } 
} 
相關問題