Linq 为什么可以';t我们在IQueryable类型的序列上调用标准查询运算符<;T>;?

Linq 为什么可以';t我们在IQueryable类型的序列上调用标准查询运算符<;T>;?,linq,Linq,标准查询运算符对实现IEnumerable接口的Linq to对象序列进行操作,而对IQueryable接口类型的序列调用Linq to Sql运算符。因此,除非先将该序列转换为IEnumerable(通过AsEnumerable运算符),否则无法对类型为IQueryable的序列调用标准查询运算符 a) 为什么不能对IQueryable序列调用没有Linq到Sql对应项(如Reverse())的标准查询运算符?也就是说,IQueryable派生自IEnumerable,因此扩展实现IEnume

标准查询运算符对实现
IEnumerable
接口的Linq to对象序列进行操作,而对
IQueryable
接口类型的序列调用Linq to Sql运算符。因此,除非先将该序列转换为
IEnumerable
(通过
AsEnumerable
运算符),否则无法对类型为
IQueryable
的序列调用标准查询运算符

a) 为什么不能对
IQueryable
序列调用没有Linq到Sql对应项(如
Reverse()
)的标准查询运算符?也就是说,
IQueryable
派生自
IEnumerable
,因此扩展实现
IEnumerable
的类的扩展方法也应该扩展实现从
IEnumerable
派生的接口的类

b) 无论如何,为什么能够对类型为
IQueryable
的序列调用标准查询运算符(那些没有Linq到Sql对应项的查询运算符)而不首先将此序列强制转换为
IEnumerable
(通过
AsEnumerable
运算符)是个坏主意


thanx

如果我正确理解了您的问题,Linq to SQL查询会生成SQL查询,因为Linq to SQL是不同的Linq提供程序,IEnumerable用于内存集合中的查询

IQueryable
通常不仅仅用于Linq to SQL,这是一种约定,任何查询提供程序都可以选择使用一组有限的操作来支持—并非所有查询提供程序都支持相同的子集


所支持的子集取决于查询提供程序域中有意义的内容
IQueryable
在表达式树上操作,该表达式树允许查询提供程序将查询转换为基础数据源的特定于域的语言(即SQL)

我记得不久前有人问我类似的问题。《碎玻璃》非常成功。作为一个表达式,一个函数或函数列表,可以考虑IQueRelaby.IEnumerable是内存中的结果—无论它们是从IQueryable还是其他来源派生的。一旦理解了这一点,您就会明白为什么IEnumerable的函数不能在IQueryable上工作+我必须承认我对表达式树一无所知。无论如何,从C#语法规则的角度来看,调用IQueryable.Reverse应该是可行的,正如我在第一篇文章中解释的那样。我很好奇为什么C#规则在这里不适用?@flockofcode:它们确实适用-这不会创建编译时错误(因为扩展方法是为
IQuerable
定义的,但是如果不受支持(即,如果查询提供程序映射到的域中没有等效项),则会产生运行时错误)由您正在使用的特定查询提供程序提供。对于Linq to SQL,即,您在尝试使用TakeWhile、SkipWhile、Reverse、Last、LastOrDefault等时将出现异常。我正在阅读的书中的完整列表声称:“IQueryable接口没有反向方法,因此引发了异常。”,这是没有意义的,因为如果没有为IQueryable定义Reverse,那么我们应该能够在IQueryable序列上调用Linq to对象的Reverse。无论如何,感谢你们两位的帮助