1

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

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

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

谢谢你

4

1 回答 1

1

首先context.Contacts由 EF 查询提供程序处理,它将表达式 (from IQueryable) 转换为 SQL。

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

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

您可能知道,当您擦除AsEnumerable整个语句时Expression,EF 会将其转换为一个 SQL 语句。

于 2012-10-29T21:48:03.450 回答