gpt4 book ai didi

c# - EF 4.3 使用本地缓存而不是从数据库中重新获取

转载 作者:太空宇宙 更新时间:2023-11-03 20:24:26 25 4
gpt4 key购买 nike

有人可以向我解释为什么我下面的 EF (4.3) 代码优先代码导致检索到“旧”密码。

using (var context = new CableSenseInstanceConfiguratorContext())
{
var user = context.Installers.Where(u => u.UserName == "admin").FirstOrDefault();
Console.WriteLine(user.Password); // Outputs "oldpassword"

// Change the details on a different context;
using (var context2 = new CableSenseInstanceConfiguratorContext())
{
var installer = context2.Installers.Single(i => i.UserName == "admin");
installer.Password = "changed";
context2.SaveChanges();
}

var user2 = context.Installers.Where(u => u.UserName == "admin").FirstOrDefault();
Console.WriteLine(user2.Password); // Outputs "oldpassword"
}

密码是“oldpassword”开始。所以我在另一个上下文 (context2) 中更改密码,然后再次将其提取到 user2 中。我可以验证两者的输出都是“oldpassword”。通过分析 SQL,我可以看到密码确实发生了更改,我还可以看到填充 user2 的代码 IS 进入了数据库,但它只是没有使用这些值。

我知道 EF 有本地上下文的概念作为缓存和跟踪实体的一种方式,但据我了解,context.Installers.Where(..) 应该强制重新获取来自数据库,而 context.Installers.Find() 应该在本地上下文中查找。看来无论我怎么查询Installers,都是使用本地缓存。

编辑

感谢@Reinard 提供的解决方案。我误解了文档 - 我读自 here :

Note that DbSet and IDbSet always create queries against the database and will always involve a round trip to the database even if the entities returned already exist in the context.

所以我假设因为它会进入数据库,所以它会重新获取我的对象。实际发生的是它进入数据库,获取对象,发现我已经在跟踪那个对象(因为之前的加载),所以我最终得到了旧对象——这实际上是文档所说的!

令人惊讶的是,使用 context.Installers.Local.Clear() 没有任何区别,我需要 AsNoTracking()。

最佳答案

WhereFind 都不会显式地从数据库中重新获取。据我所知,只有在上下文中不存在实体时,Find 才会从数据库中检索该实体。

为了显式强制重新获取,请使用 AsNoTracking()。

例如

context.Installers.AsNoTracking().Where(u => u.UserName == "admin").FirstOrDefault();

关于c# - EF 4.3 使用本地缓存而不是从数据库中重新获取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11393068/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com