在实体框架中,DbSet.Local 保持不同步

Posted

技术标签:

【中文标题】在实体框架中,DbSet.Local 保持不同步【英文标题】:in Entity Framework, DbSet.Local remains out of sync 【发布时间】:2017-12-22 09:01:09 【问题描述】:

这个让我发疯:我有一个基于数据库的 EF 模型,该数据库包含一个名为 Category 的表,其中包含 6 行。 我想在 WPF 的下拉列表中显示它,所以我需要将它绑定到 Categories.Local Observable 集合。 问题是这个可观察的集合永远不会收到数据库表的内容。我的理解是,在使用SaveChanges() 执行查询或保存数据时,集合应该与数据库同步,所以我运行了以下 2 个测试:

  Categories = _db.Categories.Local;

  // test 1
  Debug.WriteLine(_db.Categories.Count());
  Debug.WriteLine(_db.Categories.Local.Count());

  // test 2
  _categories.Add(new Category()  CategoryName = "test" );
  _db.SaveChanges();
  Debug.WriteLine(_db.Categories.Count());
  Debug.WriteLine(_db.Categories.Local.Count());
  Debug.WriteLine(_categories.Count());

测试 1 在数据库中显示 6 行,在本地显示 0。 测试 2 在数据库中显示 7 行,在本地显示 1 行(两个版本)

我也尝试使用_db.Category.Load(),但正如预期的那样,它不起作用,因为它是数据库优先,而不是代码优先。

我还浏览了这个页面https://msdn.microsoft.com/en-us/library/jj574514(v=vs.113).aspx,创建了一个基于对象的数据源并将我的组合框链接到它,但没有成功。

有谁知道我做错了什么? 提前感谢您的帮助。

【问题讨论】:

为什么你认为_db.Category.Load(); 不起作用?它不是特定于代码的。请注意,_db.Categories.Count() 会转换为 SQL 查询,并且不会将任何内容加载到上下文中。 我输入了_db.Category.Load();,它说方法未知。你试过了吗?我同意Count() 可能无法完成这项工作,但我不明白如何在添加项目并保存更改后计数为 1,而数据库中有 7 行。 这是一种自定义扩展方法。 using System.Data.Entity; 应该允许您访问它(以及 QueryableExtensions 类中的许多其他人)。 Load 基本上是 ToList 没有创建列表(只是为了填充 DbSet.Local)。 嘿!有用!太感谢了!现在,我怎样才能将此标记为答案?你想写下答案以便我标记它吗? 不客气,很高兴它有帮助 :) 你去了。 【参考方案1】:

DbSet<T> 类是IQueryable<T>,因此DbSet<T>.Count() 方法映射到Queryable.Count<T> 扩展方法,该扩展方法又被转换为SQL 查询并返回数据库表中的记录数没有 将任何内容加载到数据库上下文本地缓存中。

DbSet<T>.Local 只是让您访问本地缓存。它包含您添加的实体以及由返回 T 实例的查询加载的实体(或通过导航属性引用 T 的其他实体)。为了完全加载(填充)本地缓存,您需要调用Load

 _db.Categories.Load();

LoadQueryableExtensions类中定义的自定义扩展方法,所以需要包含

using System.Data.Entity;

为了访问它(以及键入 IncludeXyzAsync 和许多其他 EF 扩展方法)。 Load 方法等效于 ToList,但没有创建额外列表的开销。

一旦你这样做了,绑定就会起作用。请注意,Local 不会反映通过不同的DbContext 实例或不同的应用程序/用户对数据库所做的更改。

【讨论】:

以上是关于在实体框架中,DbSet.Local 保持不同步的主要内容,如果未能解决你的问题,请参考以下文章

数据直接绑定到商店查询

EF实体框架之CodeFirst七

实体框架5与Oracle表/视图不存在不一致?

了解实体框架启用迁移和上下文

具有实体框架和空间数据的持久无知域

实体框架和业务对象