LINQ编码如何工作?幕后发生了什么?

Dan*_*iel 2 linq clr

例如:

m_lottTorqueTools = (From t In m_lottTorqueTools _
                     Where Not t.SlotNumber = toolTuple.SlotNumber _
                     And Not t.StationIndex = toolTuple.StationIndex).ToList
Run Code Online (Sandbox Code Playgroud)

这里出现了什么算法?在后台是否有嵌套的for循环?它是否为这些字段构建哈希表?我很好奇.

Jon*_*eet 6

通常,查询表达式被转换为扩展方法调用.(他们不具备是,但查询的99.9%,使用IEnumerable<T>IQueryable<T>.)

该方法的确切算法因方法而异.例如,您的示例查询不会使用任何哈希表,但会加入或分组操作.

简单的Where调用转换为C#中的类似内容(使用迭代器块,据我所知,目前在VB中不可用):

 public static IEnumerable<T> Where(this IEnumerable<T> source,
     Func<T, bool> predicate)
 {
     // Argument checking omitted
     foreach (T element in source)
     {
         if (predicate(element))
         {
             yield return element;
         }
     }
 }
Run Code Online (Sandbox Code Playgroud)

谓词作为委托(或表达树,如果您正在使用IQueryable<T>)提供,并在序列中的每个项目上调用.流式传输结果和延迟执行 - 换句话说,直到您开始从结果中请求项目时才会发生任何事情,即使这样,它只会为了提供下一个结果而执行所需的操作.一些运算符不是延迟的(基本上是返回单个值而不是序列的运算符)并且一些缓冲区输入(例如,Reverse必须在它返回任何结果之前读取到序列的末尾,因为它读取的最后一个结果是它必须得到的第一个).

详细介绍我担心的每一个LINQ运算符都超出了单一答案的范围,但如果您对特定问题有疑问,我相信我们可以帮忙.

我应该补充说,如果您使用的是LINQ to SQL或其他基于提供程序的提供程序IQueryable<T>,那么事情就会有所不同.该Queryable班建立了查询(与供应商,它实现的帮助下IQueryable<T>由供应商开始),然后查询,一般翻译成一个更合适的形式(例如SQL).确切的细节(包括缓冲,流式传输等)将完全取决于提供商.