【问题标题】:Calling database upon ToList() method call在 ToList() 方法调用时调用数据库
【发布时间】:2012-05-07 09:24:47
【问题描述】:

从我的存储库中,我使用 ToList() 方法返回不同的列表。

问题是,当我对这个返回的结果(即 List 类型)运行更多 LINQ 时,它也会为此生成一个数据库调用。显然,这第二个 linq calll 是纯 LINQ to Entity,不应调用数据库。请参阅下面我在做什么。

List<User> us = userRepository.GetMany(u => filterStatusIds.Contains(u.UserStatus.Id));
if (!string.IsNullOrEmpty(name))
us = (from u in us
      where u.DisplayName.Contains(name)
      select u).ToList(); // this ToList should not call database

有什么帮助或想法来阻止这个额外的数据库调用吗?

【问题讨论】:

  • 为什么会再次执行数据库查询?另外为什么你在你的应用程序而不是数据库中执行过滤器?
  • @abatishchev:第一次调用ToList 将切换到 linq-to-objects 并且没有回头路,因为结果已物化并且表达式树消失了。
  • @Ladislav:当然,你是对的,误读了你最初的评论。

标签: c# linq linq-to-entities entity-framework-4.2


【解决方案1】:

从存储库返回IEnumerable&lt;User&gt;IQueryable&lt;T&gt;,它不会查询数据库。

在 ToList() 之后,只有第二次调用会执行此操作。

【讨论】:

  • 出于兴趣 - 这是否意味着在第一个查询中 List&lt;User&gt; 的返回类型会强制枚举结果? IE。这不仅仅是IEnumerableList 之间的某种转换,而是涉及结果的具体化(ToList() 是隐含的)?这对我来说应该是显而易见的,但如果你能确认,我会很高兴。
  • 我尝试了一个使用 List 过滤的简单示例,并且没有调用 ToList,编译器只是告诉我 IEnumerable 不能隐式转换为列表。这个例子有什么不同吗?在示例的第一行中它是如何工作的?
  • @Joanna:是的,调用 ToArray()/ToList() 会导致具体化。因此,如果方法仅“按原样”返回 IEnumerable/IQueryable,则不会发生具体化。在第一个 m-z 之后,您从 LINQ 切换到实体到 LINQ 到对象,即将第一个过滤结果加载到服务器内存中并在每个下一个过滤器中将其枚举到内存中。
  • @Joanna:所以如果你想返回非物化数据,不要在返回/查询时调用 m-z 方法,并“简化”返回类型,以匹配。
  • @Joanna:imo,这在 LINQ to Database 的情况下是可以理解和有用的,但在 LINQ to XML 中则少得多。我曾经陷入过它的陷阱。
猜你喜欢
  • 1970-01-01
  • 2020-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多