实体框架代码优先 - 孤立解决方案?
Posted
技术标签:
【中文标题】实体框架代码优先 - 孤立解决方案?【英文标题】:Entity Framework Code First - Orphaning solutions? 【发布时间】:2012-11-20 14:04:12 【问题描述】:我已经搜索了很长时间,试图为 EF 中常见的孤立问题找到令人满意的解决方案。
最简单的孤立形式之一是清除实体集合。实体之间的关系已删除,但子实体仍保留在数据库中。
我的要求:-
集合的清除发生在域中,我希望能够简单地调用 clear 而不是更多。 任何判断父子关系是否被破坏导致删除的逻辑都需要封装在存储库/DbContext中。 我不想为了解决这个问题而用任何额外的东西“弄脏”域。这包括反向引用。我怀疑这无法解决,因为我已经花费了大量时间寻找解决方案,但我是出于希望而提出的!
我查看的区域是 ChangeTracker 和我可以挂钩的任何可能的事件,类似于在各个地方弹出的 AssociationChanged 事件。 DbContext 中的某处必须知道这种关系已被破坏。如何访问它,这是个问题?
谢谢。
【问题讨论】:
【参考方案1】:您可以尝试以下解决方案吗? Mb 它适合您的需求。必须在 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);
【讨论】:
以上是关于实体框架代码优先 - 孤立解决方案?的主要内容,如果未能解决你的问题,请参考以下文章