【问题标题】:IEnumerable filtration inside sql rather than memory?IEnumerable在sql而不是内存中过滤?
【发布时间】:2017-03-30 02:05:58
【问题描述】:

我看到很多帖子都在谈论 IEnumerable,它在内存中应用过滤,而不是像 IQueryable 这样的 SQL 服务器。

但是,

我的桌子有20 recordsonly one has Id = '12345'

当我这样做时

IEnumerable<Customer> customer = _context.Customer.where(x => x.Id== '12345');

它返回1 行和not of 20 行。 为什么?

我的理解是它最初会返回 20 行,稍后我会返回

var result = customers.ToList(); 

它将返回 1 条记录。

【问题讨论】:

  • 它不返回任何行。它返回一个表达式,当您迭代结果时将对其进行评估。该表达式包含一个“where”子句,该子句将包含在该评估中。
  • 您对“延期执行”的含义有误解。这并不意味着将返回所有 20 行。想想曾经用 Entity Framework 编写的每个查询,这将是多么昂贵。它的意思是您的查询就是:一个查询。在您通过某种形式的迭代强制执行它之前,它不会被执行——无论是foreachToListToArray 等等。
  • 还要注意,仅仅因为customer 被声明为IEnumerable&lt;Customer&gt; 类型并不意味着它不能容纳IQueryable&lt;Customer&gt;IQueryable&lt;T&gt; 实现IEnumerable&lt;T&gt;: msdn.microsoft.com/en-us/library/… 所以不管你是否把它当作IEnumerable&lt;Customer&gt;,在你的例子中,底层对象都是IQueryable&lt;Customer&gt;

标签: c#


【解决方案1】:

此时,您在 IQueryable 接口上执行where。 (记住=的右边比左边先执行)

IEnumerable<Customer> customer = _context.Customer.Where(x => x.Id == 12345);

你读到的内容是这样的:

IEnumerable<Customer> customers = _context.Customer
IEnumerable<Customer> clientFiltered = customers.Where(x => x.Id == 12345);

如果您想以 oneliner 的身份执行此操作:

_context.Customer.AsEnumerable().Where(x => x.Id == 12345);

注意,在后面的 2 种情况下,您先将其转换为 IEnumerable,然后再进行更具体的 Where

【讨论】:

  • 啊啊这就是我错过的重点。基本上用 Where 子句编写一行 IEnumerable 实际上意味着您上面提到的两行查询。所以过滤是在内存中的 IEnumerable 正确吗?这就是我得到 1 条过滤记录而不是 20 条记录的原因。正确吗?
猜你喜欢
  • 2019-09-27
  • 2020-03-07
  • 1970-01-01
  • 2020-03-02
  • 1970-01-01
  • 2017-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多