C# 实体框架:处理分离的对象和附加的对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/389432/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Entity Framework: Working with detached objects and attached ones
提问by biozinc
Firstly, let me set out what I'd like to do. Assume I have three types of EntityObject
, MetaData
, Data1
and Data2
. MetaData
is, as one would expect, has a reference to one instance each of Data1
and Data2
. Now, for each MetaData
, I can calculate a value
.
首先,让我列出我想做什么。假设我有三种EntityObject
,MetaData
,Data1
和Data2
。MetaData
正如人们所期望的那样, is 对每个Data1
和 中的一个实例都有一个引用Data2
。现在,对于每个MetaData
,我可以计算一个value
。
So far so simple. Now, I would like the user to play around with various combinations of Data1
and Data2
, and see what value
s they can get. This obviously requires creation of instances of MetaData
. Now, if I don't want to cluter the database with all these entries of MetaData
, then I'd like to create the entity objects in the in-memory context without calling a SaveChanges()
to write it back to the DB. However, this presents a problem in that whenever I try to access the Data1
and Data2
references of the in-memory MetaData
, I end up with the following exception:
到目前为止如此简单。现在,我想用户玩弄的各种组合Data1
和Data2
,看看value
就是他们可以得到的。这显然需要创建MetaData
. 现在,如果我不想用 的所有这些条目弄乱数据库MetaData
,那么我想在内存上下文中创建实体对象,而无需调用 aSaveChanges()
将其写回数据库。但是,这带来了一个问题,因为每当我尝试访问in-memory的Data1
和Data2
引用时,我都会遇到MetaData
以下异常:
InvalidOperationException is unhandled
InvalidOperationException 未处理
The source query for this EntityCollection or EntityReference cannot be returned when the related object is in either an added state or a detached state and was not originally retrieved using the NoTracking merge option.
当相关对象处于添加状态或分离状态并且最初未使用 NoTracking 合并选项检索时,无法返回此 EntityCollection 或 EntityReference 的源查询。
If I do as suggested, and "committ" the object to DB, I end up with the clutter problem.
如果我按照建议进行操作,并将对象“提交”给 DB,我最终会遇到混乱的问题。
Anyhow, the guilty code looks something like this:
无论如何,有罪代码看起来像这样:
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();
It seems this guyhad a similar problem.
看来这家伙也有类似的问题。
采纳答案by Craig Stuntz
IsLoaded is only relevant for properties of instances which have been materialized from a database. As you've discovered, it does not return useful information for instances which have not been materialized from a database.
IsLoaded 仅与已从数据库具体化的实例的属性相关。正如您所发现的,对于尚未从数据库中具体化的实例,它不会返回有用的信息。
Therefore, you should change the way you test whether or not you want to call Load(). If you know that you will be working with instances of MetaData which you have only created in memory and not materialized from a database, then you could write code like this:
因此,您应该更改测试是否要调用 Load() 的方式。如果您知道您将使用仅在内存中创建而不是从数据库中具体化的 MetaData 实例,那么您可以编写如下代码:
if ((temp.EntityState != System.Data.EntityState.Added) &&
(!temp.Data1Reference.IsLoaded)) temp.Data1Reference.Load();
I'm glossing over some subtleties, here. For starters, EntityState is declared with FlagsAttribute, so it can containAdded without being equalto Added. Also, none of this is necessary if Data1Reference is non-null, so you might just want to test for that first. The point is, you can write code which suits your situation, but it must account for the full state of temp, not just its properties.
我在这里掩盖了一些微妙之处。对于初学者来说,EntityState 是用 FlagsAttribute 声明的,因此它可以包含已添加而不等于已添加。此外,如果 Data1Reference 为非空,则这些都不是必需的,因此您可能只想先测试一下。关键是,您可以编写适合您情况的代码,但它必须考虑到 temp 的完整状态,而不仅仅是它的属性。