2015-09-15 30 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); 
    } 
} 
相关问题