当我们对序列调用查询运算符时,会调用特定于序列的运算符。
我的意思是如果我打电话Where<>()
操作符开启IEnumerable<>
,将被调用的运算符将在 Enumerable 类中定义,并且如果它被调用IQueryable<>
,将调用 Queryable 类中定义的类。
考虑 Enumerable 类中定义的运算符 Reverse。
如果我想打电话Iqueryable<>
那么我必须使用AsEnumerable<>()
运算符首先将其转换为IEnumerable<>
.
db.Countries.OrderBy(cntry=>cntry.CountryName).AsEnumerable().Reverse()
但是 Reverse 运算符必须同时拥有所有记录,以便可以反转它们。
在上面的代码中,所有记录是否首先加载到内存中,然后 Reverse() 运算符将其反转?
AsEnumerable
除了更改表达式的编译时类型之外什么也不做。
它的实现是这样的:
public static IEnumerable<T> AsEnumerable<T>(this IEnumerable<T> source)
{
return source;
}
它甚至不检查是否无效!
唯一的一点是更改编译时类型,以强制使用 Enumerable 扩展方法而不是 Queryable 执行查询的其余部分。它就像一个强制转换 - 只是在查询过程中强制转换通常会很不方便,并且对于匿名类型,您无论如何都无法对其进行强制转换。
因此,这实际上与查询的“源”在枚举时执行的操作有关。该源是否在返回任何结果之前将所有内容加载到内存中,或者是否流式传输它们? IIRC,LINQ to SQL 实际上会将所有内容加载到内存中 - 但我可能是错的。当然Reverse
无论如何都会缓冲任何东西,但这并不意味着它会使用双倍的内存 - 在大多数情况下,这只意味着它会缓冲参考对物体;它不会创建每个对象的新副本。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)