【问题标题】:Unused results from Entity Framework database call实体框架数据库调用的未使用结果
【发布时间】:2015-06-04 23:03:33
【问题描述】:

任何体面的编译器都应该eliminate dead code,至少在一定程度上是这样。但是,我很好奇编译器(特别是 MSBuild)如何处理如下情况:

// let's assume LazyLoadingEnabled = false;
var users = db.Users.ToList();
// more code that never touches 'users'

由于LazyLoadingEnabled = false,编译后的代码:

  1. 从数据库调用中快速加载结果

  2. 调用数据库而不存储结果

  3. 从不打电话?

我在工作中清理了一些旧代码,我发现了几个发生这种情况的案例,所以我很好奇我们是否一直在浪费资源。

感觉正确的答案是 3,但我还没有找到任何确凿的证据来支持我的说法。感谢您的帮助!

【问题讨论】:

  • 调用db.Users.ToList() 并非没有副作用。该调用在上下文中创建User 实体,因此即使不使用users,这些实体仍然可以使用。例如,如果随后使用相同的 dbContext 调用类似 db.Users.Find() 的内容,如果实体存在于本地,则该函数不会产生对数据库的调用。
  • @jjj 有趣。为了清楚起见,我应该删除ToList() 吗?
  • 我对此并不完全确定,但我认为在 DbContext 中引用 DbSet 属性可能会触发一些 DbContext 初始化,如果之前未初始化上下文。

标签: c# entity-framework msbuild dbcontext compiler-optimization


【解决方案1】:

答案是 #1。

这不仅会执行数据库查询以从Users 表中选择所有记录,而且还将获取所有这些记录并为Users 表中的每条记录构造实体。如果您有很多记录,则非常昂贵。当然,GC 最终会收集浪费的资源。

如果您想自己证明上述内容,只需在创建 DbContext 后添加以下行以记录正在执行的 SQL:

db.Database.Log = s => Console.WriteLine(s);

顺便说一句,LazyLoadingEnabled 设置对观察到的行为没有影响。 LazyLoadingEnabled 设置确定是否急切加载导航属性。在这种情况下,db.Users 不是导航属性,因此没有任何作用。

【讨论】:

  • 哇。因此,无论我从未使用过该变量,都会发生这种情况?
  • 是的。事实上,变量赋值是无关紧要的。如果你只做db.Users.ToList();,没有任何变量赋值,你将遇到完全相同的问题。
猜你喜欢
  • 2018-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多