LINQ的“Where”方法如何工作?

时间:2010-10-05 10:08:03

标签: c# linq

究竟LINQ的“where”方法是如何定义的?我猜测实现是这样的:

public static IEnumerable<T> Where ( this partialParent, Func<bla,bla> myDelegate ) 

现在,如果我调用Where这样的方法:

from c in context.Con
where ( c.Col1 == c.Col2 )
select c

我猜测传递"c.Col1 == c.Col2"并且一些foreach循环执行检查。但是当我调用这样的地方时会发生什么:

where ( c.Col1 == c.Col2 || c.Col3 == c.Col4 )

这两个“检查”是否作为一个整体表达式传递下来?也许我错过了一些非常简单的事情。

3 个答案:

答案 0 :(得分:3)

对于linq-to-objects,您可以将其视为等同于enumeration.Where(c => c.Col1 == c.Col2)enuemration.Where(c => c.Col1 == c.Col2 || c.Col3 == c.Col4)

实施Where的最简单方法是:

public static IEnumerable<T> Where<T>(this IEnumerable<T> src, Func<T, bool> pred)
{
  foreach(T item in src)
    if(pred(item))
      yield return item;
}

虽然如果你看一下反射器中的代码,你会看到很多关于这个基本思想的优化。

但是,对Where的此调用只是where可以实现的一种方式。因为LINQ查询可以针对许多不同的可查询源执行,所以还有其他可能性。例如,可以将其转换为发送到数据库的查询的SQL WHERE子句。使用Linq2SQL执行一些查询可以提供信息,并运行SQL事件探查器并查看发送到服务器的内容。

答案 1 :(得分:2)

以下“伪”代码块提供相同的代码:

// first
from item in sequence
where expression
select item;

// second
sequence.Where(item => expression);

只要它产生一个布尔结果,在表达式中进行多少次比较并不重要。它仍然是一种表达方式。

这意味着以下两个也是相同的:

// first
from c in context.Con
where ( c.Col1 == c.Col2 || c.Col3 == c.Col4 )
select c;

// second
context.Con.Where(c => c.Col1 == c.Col2 || c.Col3 == c.Col4);

答案 2 :(得分:0)

您为where提到的查询语法基本上创建了一个方法和委托,并使用它调用方法语法版本。无论你用where调用什么,都会转换为单个方法,然后通过委托对源序列的每个元素进行调用。

所以可能你的意思是两个检查作为一个整体表达式传递;这就是发生的事情......

where ( c.Col1 == c.Col2 || c.Col3 == c.Col4 )

它变成了这样一个方法调用:

bool MethodExample(var c){
  return ( c.Col1 == c.Col2 || c.Col3 == c.Col4 );
}

然后在每个元素上调用。 (显然上面是伪代码)