簡體   English   中英

實體框架,獲取孤兒的孩子記錄/沒有父母的記錄

[英]Entity framework, Get orphans child records/records without parents

保存數據庫上下文時出現以下異常:由於一個或多個外鍵屬性不可為空,因此無法更改該關系。

如前所述這里 ,這可能是由於缺少級聯刪除。 但是,這不是我的代碼,我也不知道哪個表可以包含孤立記錄。 錯誤消息不這樣說。

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

然后,我將能夠指出需要調整的代碼的哪一部分。

在實體框架中,當您具有多對多關系時,您嘗試從諸如parent.Children.Remove(child)類的對象中刪除時,這只會將子項與中間連接表分離。 因此,您必須找到該子項並將其從DbContext ChildrenToParent實體中刪除,例如DbContext.ChildrenToParent.Remove(child) 如果您提供一些代碼示例和/或數據庫圖,我想我可以更准確地解釋一下。

您可以嘗試以下解決方案嗎? 必須在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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM