与Linq-to-Objects查询操作的Linq-to-Objects查询有些混淆

时间:2012-10-29 20:54:46

标签: linq-to-entities linq-to-objects

Linq to objects表达式返回一个对象,枚举时会从序列中生成元素。通常,延迟的LINQ-to-Object方法充当管道,因此序列的每个元素在处理下一个元素之前流经处理管道。

a)但是如果Linq-to-Objects查询对Linq-to-Entities查询的结果进行操作,那么当foreach尝试迭代search时,每个元素再次流经整个处理处理下一个元素之前的序列(换句话说,是从DB检索的序列中的第一个元素,然后由Enumerable.Where处理,然后由Enumerable.SelectMany处理,然后才是从DB中检索的下一个元素)或者是从DB一次检索的整个元素集(当foreach尝试从序列中读取第一个元素时),然后这些元素才开始流经Linq-to-Objects运算符的处理管道? / p>

        var search = context.Contacts.AsEnumerable().
            Where(s => s.ContactID > 10).SelectMany(s => s.Address);

谢谢

1 个答案:

答案 0 :(得分:1)

EF查询提供程序处理第一个context.Contacts,它将表达式(从IQueryable)转换为SQL。

然后,通过AsEnumerable,与EF查询提供程序的链接被破坏,之后的任何内容都是对象的linq,处理前一语句的结果集。

但是,由于Contact.Address是一个延迟加载的集合,对于传递管道的每个Contact,会发出一个新查询来填充它。这是可能的,因为EF使用Contact的代理类型,它通过EF查询提供程序运行查询的getter覆盖Address

正如您可能知道的那样,当您擦除AsEnumerable时,整个语句将变为Expression树,EF将转换为一个SQL语句。