【发布时间】:2010-10-07 07:31:42
【问题描述】:
为什么要在数据库中找到已在 ObjectContext 中表示的记录?
所以这就是我认为当您查询时会发生的情况:
SiteUser someUser = context.SiteUser.Where(role => role.UserID == 1).ToList()[0];
垃圾示例,但我的想法是我想从 id 为 1 的表中获取用户。现在假设这是第一次通过,所以我猜它必须在上下文中创建 SiteUser 列表,查询数据库,然后填写它的列表。使用分析器我看到了这个:
SELECT
[Extent1].[UserID] AS [UserID],
[Extent1].[MainEmail] AS [MainEmail],
[Extent1].[Password] AS [Password],
[Extent1].[UserName] AS [UserName]
FROM [TIDBA].[TI_USER] AS [Extent1]
WHERE 1 = [Extent1].[UserID]
美丽。它达到了我的预期,在 SiteUser 列表中(如果我使用 Watch 挖掘得足够远)我可以看到上下文 SiteUser 列表中有一个项目,它恰好是代表此数据行的水合对象。
接下来我想更改一些内容而不保存:
someUser.UserName = "HIHIHI";
现在说出于某种原因我想再次抓取它使用相同的上下文(这是一个奇怪的例子,但它实际上是一个测试,所以我可以证明这种情况发生):
someUser = context.SiteUser.Where(role => role.UserID == 1).ToList()[0];
我认为会发生的是它会查看上下文中的 SiteUser 列表,因为这就是生成的属性所说的。 (如果不为空,则返回列表)然后它会查看它是否存在并返回它。没有数据库命中。猜猜探查器怎么说...
SELECT
[Extent1].[UserID] AS [UserID],
[Extent1].[MainEmail] AS [MainEmail],
[Extent1].[Password] AS [Password],
[Extent1].[UserName] AS [UserName]
FROM [TIDBA].[TI_USER] AS [Extent1]
WHERE 1 = [Extent1].[UserID]
嗯。好的,所以我开始认为,也许这是一个直觉检查,看看该数据项是否发生了任何变化,并仅在客户端上未更改的值上更新 SiteUser 对象。 (有点像 context.Refresh(RefreshMode.ClientWins, context.SiteUser) )所以我把它停在了:
someUser = context.SiteUser.Where(role => role.UserID == 1).ToList()[0];
我更改了数据库中的一个值(密码列)并让它进入数据库。对象没有任何变化。
这里似乎有些不对劲。它会访问数据库以选择我已经在上下文中水合的对象,但它不会应用我在数据库中手动进行的更改。那它为什么还要访问数据库呢?
更新 感谢下面的一些链接,我能够挖掘一下并找到这个:
看起来有一个枚举设置来告诉如何处理负载。现在读完之后,我看到了 MergeOption.AppendOnly:
已经存在的对象 对象上下文不是从 数据源。这是默认设置 查询或调用时的行为 上的 Load 方法 EntityCollection)>).
这表明如果我在上下文中使用它,则不会对数据库造成任何影响。然而,这似乎不是真的。如果 OverwriteChanges 或 PreserveChanges 是默认值,那将是有意义的,但它们不是。这似乎与应该发生的事情相矛盾。我唯一能想到的是“加载”只是意味着没有覆盖。但是,这并不意味着没有对数据库的查询。
【问题讨论】:
标签: entity-framework