【发布时间】:2017-06-09 16:47:30
【问题描述】:
我正在开发一个使用实体框架的应用程序,但我遇到了一些性能问题。 想象一个带有一些组合框和数据网格的用户界面(C#、WPF)。每次在组合框中选择一个值时,它都会更改数据在网格中显示的条件。 看起来实体框架在缓存方面没有我想象的那么灵活。由于条件的变化,底层 sql 总是会略有不同(= 没有 EF 缓存),并且每次单元格更新都会导致对数据库的请求。
有什么方法可以在本地缓存表(使用有效的导航属性)并仍然使用 linq 进行选择等,而不会对数据库产生任何请求?
- 这些表很小,所以我预计不会出现任何性能问题。 (一世 猜测本地排序等。否则可能是一个问题,因为没有使用数据库索引。)
- 我不需要对表的写入权限,所以如果 有一种简单的方法可以制作表格的深层副本并分离 从数据库连接可能没问题。
- 我不允许安装任何第三方工具。
也许实体框架从一开始就是一个糟糕的选择,但是使用那些生成的类和linq真的很方便,而不是手动编写大量的类和sql。 (我仍然需要实现一些缓存。)
【问题讨论】:
-
我认为你应该展示一些你的代码。在将 Queryable 提供给组合框和数据网格(有效地从 EF linq 切换到内存 linq)之前,这听起来像是 Queryable 上的一个简单 ToList() 可能对解决您的问题大有帮助。
-
EntityFramework(EF) 一旦你得到对象就不必使用了。它只是一个用于获取数据的对象模型层。 LINQ 与 EF 是分开的,因为 EF 将数据库对象化以进行数据检索。您可以简单地设置一个存储库模式,您可以在其中在设定的持续时间内执行检索方法并缓存这些对象。我可以很容易地做到 var ls = new List
{ "a", "b", "c", "d", "e"}。 ls.Distinct().Skip(2).Take(3).ToList().ForEach(x => Console.WriteLine($"我有 {x}")); EF与Linq无关,它的用途,LINQ是查询扩展方法的框架,EF是数据检索 -
另外,您在这里一针见血:“但使用那些生成的类真的很方便”。 T4 模板(生成这些类的内容)是 EF 真正闪耀恕我直言的地方。如果需要,您也可以覆盖编写代码的代码也生成生成的数据。 EG:假设我有一个表 colors: 它只存储一个 id 和值 'red'、'blue'、'yellow'。检索这有点愚蠢,所以我什至可以破解 T4 以生成枚举生成的对象,这些对象是数据库中的内容。可能不适合生产,因为数据库更改需要重新运行 T4 模板。
-
Paul-Jan,这对于组合框来说没问题,但对于网格来说并不容易。单元格中的条目根据其他表中的值以不同方式组合来自多个表的数据,因此很难在单个查询中获取所有列的数据。 (但可能并非不可能。)
-
Djangojazz,问题是即使我已经检索了所有条目,当我遵循导航属性时,它似乎会触发数据库请求,例如“tableA.ToList().Where(someCondition)” 不会调用数据库,如果我已经在缓存中有 tableA 条目,但类似“tableA.ToList().navigationPropertyRefTableB.Where(someCondition).something” 似乎总是即使所有请求的数据已经被重新接收,也会导致对数据库的调用。 (我尝试在任何重要的地方使用“Include”和“ToList”。)
标签: c# wpf entity-framework linq caching