c# - Entity Framework .First() 缓存查询数据

标签 c# .net entity-framework-6

根据Entity Framework文档,Entity Framework只有在使用.Find()查询数据时才会缓存数据。

在以下示例中,我在使用 .First() 时获得了缓存的查询数据:

  static void Main(string[] args)
    {
        var trxScope = new TransactionScope();
        var context = new SekhavatDBEntities();

        //the value of Balance is Zero
        var account =
            context.Accounts.First(acc => acc.Id == new Guid("79B7AAC6-AD2D-4824-907E-16ADB4C41EE1"));            
        account.Balance = 50;

        context.SaveChanges();
        trxScope.Dispose();

        var trxScope2 = new TransactionScope();
        var account2 =
            context.Accounts.First(acc => acc.Id == new Guid("79B7AAC6-AD2D-4824-907E-16ADB4C41EE1"));

        //Balance of account2 Is 50 Now!
        trxScope2.Dispose();
    }

为什么 account2 的余额是 50?按照我的考虑,应该是0。

提前致谢

最佳答案

这里是来自documentation的相关引述:

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

...

When results are returned from the database, objects that do not exist in the context are attached to the context. If an object is already in the context, the existing object is returned (the current and original values of the object's properties in the entry are not overwritten with database values).

是否使用交易无关紧要。相关的是:

  1. EF 不会在事务回滚时将值更改回原始值(我认为它甚至不可能这样做,但无论如何)。使用 TransactionScopectx.Database.BeginTransaction 都没关系。

  2. 在您进行第二次查询时,您的 ID 为 79B7AAC6-AD2D-4824-907E-16ADB4C41EE1 的帐户已被上下文跟踪。根据上面的文档 - 查询将针对数据库进行,但此查询的结果将被丢弃并且不会覆盖当前跟踪实体的值。相反,实体将按原样返回(余额等于 50)。

要防止这种情况:

  1. 对单独的操作使用单独的上下文,尽可能避免重复使用上下文。

  2. 使用AsNoTracking。这将防止上述行为,并将始终返回数据库中的实体。

  3. 使用重新加载:

     context.Entry(account).Reload();
    

这将查询该实体的数据库并用当前数据库值覆盖所有值。

关于c# - Entity Framework .First() 缓存查询数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47638207/

相关文章:

c# - 使用 C# 验证 CSS 语法

c# - 为什么即使处理程序在 WPF 应用程序生命周期中是异步无效的,Application.Exit 事件仍然有效?

entity-framework-6 - 违反了多重性约束(在 XAF 中,当 createdObject.ObjectSpace.ModifiedObjects.Count 尚未被访问时。)

c# - 如果不存在则创建应用程序配置文件 C#

c# - 检查 EF 实体是否已存在于当前上下文中

c# - 防止一对多关系中的额外外键列

c# - 将 url 从 utf-8 编码重新编码为 iso-8859-1 编码

c# - 使用参数调用 expression.call 中的静态方法

C# 二叉搜索树问题

c# - 使用ASP.MVC编辑树状结构