The relationship could not be changed because one or more of the foreign-key properties is non-nullable

前端 未结 20 957
情书的邮戳
情书的邮戳 2020-11-22 04:44

I am getting this error when I GetById() on an entity and then set the collection of child entities to my new list which comes from the MVC view.

The

20条回答
  •  有刺的猬
    2020-11-22 05:12

    You must manually clear the ChildItems collection and append new items into it:

    thisParent.ChildItems.Clear();
    thisParent.ChildItems.AddRange(modifiedParent.ChildItems);
    

    After that you can call DeleteOrphans extension method which will handle with orphaned entities (it must be called between DetectChanges and SaveChanges methods).

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

提交回复
热议问题