c# - Entity Framework 中 DbContext 的奇怪行为

标签 c# .net entity-framework dbcontext

它是这样的:

MyDbContext ctx = new MyDbContext();

IFooRepository repo = new FooRepository(ctx);
var items = repo.GetAvailableItem().ToList(); //this will query all item.sold = false.

// here it returns three rows
foreach(var item in items) {
    item.sold = true;
}

repo.commit();     // this will call the SaveChanges() in DbContext

Thread.sleep(10000) 

// Now I quickly execute a query in SQL Server Management Studio 
// UPDATE Item SET Sold = 0;
var items02 = repo.GetAvailableItem().ToList();   // this will query all item.sold = false.

// here items02 also contains three rows
// HOWEVER, when I watch the value of item.sold in items02, it is all True

这是设计使然的行为吗?

为什么?是因为 DbContext 缓存了实体,即使再次运行相同的查询也不会刷新吗?


更新

这是我的仓库中的代码:

public IQueryable<Item> GetAvailableItem()
{
    var items = from x in DbContext.Item
                        where x.Sold == 0
                        select x;
    return items;
}

public virtual int Commit()
{
    return DbContext.SaveChanges();
}

最佳答案

好的。这是发生了什么:

  1. 创造一个新的环境。
  2. 通过调用 GetAvailableItem() 从数据库加载项目
  3. Context 将加载它们,并缓存它们。
  4. 通过上下文更新项目。所以:数据库行已更新,缓存版本也已更新。
  5. 在上下文之外(通过 SSMS)通过纯 sql 更新项目。所以:数据库行已更新。但是,由于您使用的上下文与以前相同,并且它有自己的项目版本,并且它无法知道自身外部发生了什么,因此缓存的项目版本保持原样:未更新.

如果你想让你的上下文知道自身之外的变化,最简单的方法是创建一个新的上下文并再次查询。另一种方法是通过 yourContext.Entry<YourEntityType>(entityInstance).Reload(); 显式告诉上下文从数据库重新加载实体。 .

关于c# - Entity Framework 中 DbContext 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39018736/

相关文章:

linq - 不包含 'where' 的定义和最佳扩展方法重载

c# - MVC 中下拉列表的 if else 条件

c# - System.Diagnostics.Debug 类是否有 TextWriter 接口(interface)?

c# - .AsNoTracking() 有什么区别?

c# - EntityFramework 5 - 已检测到对关系 'x' 的角色 'x' 的冲突更改

c# - 多次使用 ||和 && 操作数

c# - LINQ 打印出语法而不是结果

c# - Visual Studio - 编辑继续后出现错误 "Metadata file ' XYZ' 无法找到“

c# - 暴力破解性能: Java vs C#

c# - 按运行时已知的多个键分组