实体框架:使用分离的对象和附加的对象
Posted
技术标签:
【中文标题】实体框架:使用分离的对象和附加的对象【英文标题】:Entity Framework: Working with detached objects and attached ones 【发布时间】:2010-09-28 05:08:31 【问题描述】:首先,让我列出我想做的事情。假设我有EntityObject
、MetaData
、Data1
和Data2
三种类型。正如人们所期望的那样,MetaData
引用了Data1
和Data2
中的每一个实例。现在,对于每个MetaData
,我可以计算出一个value
。
到目前为止很简单。现在,我想让用户玩转Data1
和Data2
的各种组合,看看他们能得到什么value
s。这显然需要创建MetaData
的实例。现在,如果我不想用MetaData
的所有这些条目来混淆数据库,那么我想在内存上下文中创建实体对象而不调用SaveChanges()
将其写回数据库.但是,这会带来一个问题,即每当我尝试访问内存中 MetaData
的 Data1
和 Data2
引用时,都会遇到以下异常:
InvalidOperationException 未处理
当相关对象处于添加状态或分离状态并且最初不是使用 NoTracking 合并选项检索时,无法返回此 EntityCollection 或 EntityReference 的源查询。
如果我按照建议进行操作,并将对象“提交”到 DB,我最终会遇到混乱问题。
总之,有罪的代码看起来像这样:
MetaData temp = MetaData.CreateMetaData(0);
MetaData.Data1 = <existing Data1 from context>;
MetaData.Data2 = <existing Data2 from context>;
//Exception here
if (!MetaData.Data1Reference.isLoaded)
MetaData.Data1Reference.Load();
this guy 似乎也有类似的问题。
【问题讨论】:
【参考方案1】:IsLoaded 仅与已从数据库实现的实例的属性相关。正如您所发现的,对于尚未从数据库中具体化的实例,它不会返回有用的信息。
因此,您应该更改测试方式是否要调用 Load()。如果您知道您将使用仅在内存中创建而不是从数据库中具体化的 MetaData 实例,那么您可以编写如下代码:
if ((temp.EntityState != System.Data.EntityState.Added) &&
(!temp.Data1Reference.IsLoaded)) temp.Data1Reference.Load();
我在这里掩盖了一些微妙之处。对于初学者,EntityState 是用 FlagsAttribute 声明的,因此它可以 contain 添加而不是 equal 添加。此外,如果 Data1Reference 不为空,则这些都不是必需的,因此您可能只想先测试一下。关键是,您可以编写适合您情况的代码,但它必须考虑 temp 的完整状态,而不仅仅是它的属性。
【讨论】:
“EntityState 是用 FlagsAttribute 声明的,所以它可以包含Added而不等于Added” - 那么它不应该是(temp.EntityState & EntityState.Added) != EntityState.Added
吗?
@BlueRaja,是的,没错。我试图不离题。
所以,类似于:“(!temp.EntityState.HasFlags(System.Data.EntityState.Added)) && (!temp.Data1Reference.IsLoaded)) temp.Data1Reference.Load();”应该覆盖得更好吧?以上是关于实体框架:使用分离的对象和附加的对象的主要内容,如果未能解决你的问题,请参考以下文章
无法附加分离的实体:“ObjectStateManager 中已存在具有相同键的对象”