c# - Entity Framework 多对象上下文

标签 c# .net entity-framework architecture entity-framework-4

这个问题已经以 50 种不同的方式被问了 500 次...但又来了,因为我似乎找不到我正在寻找的答案:

我将 EF4 与 POCO 代理一起使用。

一个。 我有一张从 ObjectContext 的一个实例中获取的对象图。该 ObjectContext 已处理。

B. 我有一个从 ObjectContext 的另一个实例中获取的对象。该 ObjectContext 也已被释放。

我想使用 B 中的实体为 A 中的一堆事物设置相关属性......类似

foreach(var itemFromA in collectionFromA)
{
   itemFromA.RelatedProperty = itemFromB;
}

当我这样做时,我得到了异常:

System.InvalidOperationException occurred
  Message=The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.
  Source=System.Data.Entity
  StackTrace:
       at System.Data.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedTarget, Boolean applyConstraints, Boolean addRelationshipAsUnchanged, Boolean relationshipAlreadyExists, Boolean allowModifyingOtherEndOfRelationship, Boolean forceForeignKeyChanges)
       at System.Data.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedEntity, Boolean applyConstraints)
       at System.Data.Objects.DataClasses.EntityReference`1.set_ReferenceValue(IEntityWrapper value)
       at System.Data.Objects.DataClasses.EntityReference`1.set_Value(TEntity value)
       at 

我想我需要在处理这些实体时将它们从 ObjectContext 中分离出来,以便上面的工作......问题是,在处理时从我的 ObjectContext 中分离所有实体似乎会破坏图形。如果我做类似的事情:

objectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged)  
.Select(i => i.Entity).OfType<IEntityWithChangeTracker>().ToList()  
.ForEach(i => objectContext.Detach(i));

图中的所有关系似乎都未设置。

我该如何着手解决这个问题?

最佳答案

@Danny Varod 是对的。您应该为整个工作流使用一个 ObjectContext。此外,因为您的工作流程似乎是一个包含多个窗口的逻辑功能,所以它可能也应该使用单个演示者。然后您将遵循推荐的方法:每个演示者一个上下文。您可以多次调用 SaveChanges,这样它就不会破坏您的逻辑。

此问题的根源是众所周知的问题,即在 POCO 实体之上生成的动态代理不足以及 POCO T4 模板生成的 Fixup 方法。当您处置它时,这些代理仍然持有对上下文的引用。正因为如此,他们认为他们仍然依附于上下文,他们不能依附于另一个上下文。如何强制他们释放对上下文的引用的唯一方法是手动分离。同时,一旦您将一个实体从上下文中分离出来,它就会从相关的附加实体中移除,因为您不能在同一个图中混合使用附加和分离的实体。

您调用的代码实际上没有出现问题:

itemFromA.RelatedProperty = itemFromB;

但是在Fixup方法触发的反向操作中:

itemFromB.RelatedAs.Add(itemFromA);

我认为解决这个问题的方法是:

  • 不要这样做并为整个工作单元使用单一上下文 - 这是假定的用法。
  • 删除反向导航属性,以便 Fixup 方法不会触发该代码。
  • 不要将 POCO T4 模板与 Fixup 方法一起使用或修改 T4 模板以不生成它们。
  • 关闭这些操作的延迟加载和代理创建。这将从您的 POCO 中删除动态代理,因此它们将独立于上下文。

要关闭代理创建和延迟加载使用:

var context = new MyContext();
context.ContextOptions.ProxyCreationEnabled = false;

您实际上可以尝试编写自定义方法来分离整个对象图,但正如您所说,它被问了 500 次而且我还没有看到可行的解决方案 - 除了对新对象图的序列化和反序列化。

关于c# - Entity Framework 多对象上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5693843/

相关文章:

c# - 协作环境中 Entity Framework 中的迁移

c# - Entity Framework 多个多对多查询

c# - 如何在TPL中实现连续运行的数据流 block ?

c# - C#中的定时器问题

.net - Google Chrome 或 Firefox 可以嵌入到 WPF 中吗?

c# - Entity Framework 似乎在缓存数据

c# - RavenDB 快速子串搜索

c# - 如何在 visual studio 中为数据表中的每一行设计一个页面

c# - 编译器说缺少动态属性,但我可以看到它

c# - .NET Core 基于角色的身份 Cookie 动态过期