实体框架,获取孤儿记录/无父母记录



我在保存数据库上下文时遇到以下异常:由于一个或多个外键属性不可为空,因此无法更改关系。

如这里所述,这可能是由于缺少级联删除。但是,这不是我的代码,我不知道哪个表可以包含孤儿记录。错误信息没有这么说。

有办法检索那些孤儿的记录吗?(至少知道它们在哪个表中)

然后我就能确定我需要调整的代码的哪一部分

在实体框架中,当您有多对多的关系,并且您试图从像parent.Children.Remove(child)这样的对象中删除时,这只会从中间连接表中分离子节点。所以你必须找到孩子,并从DbContext childtopparent实体中删除它,就像DbContext.ChildrenToParent.Remove(child)。如果你给一些代码示例和/或数据库图,我想我可以解释得更准确。

您可以尝试以下解决方案吗?DeleteOrphans扩展方法必须在DetectChanges和SaveChanges方法之间调用。

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

相关内容

  • 没有找到相关文章

最新更新