如果IQueryable
接口在服务器中执行查询表达式而不是提取IEnumerable
之类的所有记录,为什么IQueryable
不会被IEnumerable
替换为DBSet<T>
可以更快,更有效率吗?
Where
有两种IQueryable
(IEnumerable
和IEnumerable
)。有没有办法调用IQueryable
版本,因为默认情况下会调用ToList()
而不调用{{1}}?
答案 0 :(得分:12)
- 如果
醇>IQueryable
在服务器中执行查询表达式 而不是提取IEnumerable
之类的所有记录,为什么IQueryable
没有 被IEnumerable
取代,它可以更快,更有效率吗?
IQueryable
和IEnumerable
代表两种不同的东西。将IQueryable
视为“问题”,它本身没有任何结果。 IEnumerable
是一个“答案”,它只有连接到它的数据,但你无法分辨产生该数据的是什么。
并不是说IQueryable
每个说法“更快”,它只是允许你将过滤和投影放到你向SQL服务器询问的“问题”中,让它只返回答案吧需要(通过调用IEnumerable
或类似内容以.ToList()
的形式)。
如果您只使用IEnumerable
唯一可以问的问题是“给我你知道的一切”然后在答案上给你进行过滤和预测。这就是为什么IQueryable
被认为更快的原因,因为需要处理的数据要少得多,因为您可以向服务器提出更具体的问题。
IQueryable
到处都没有替换IEnumerable
的原因是因为您提出的问题必须能够理解您提出的问题。需要做很多工作才能解析您可能要求它过滤或投影的所有可能的事情,以便大多数实现limit themselves to only common things they know they need to be able to answer。例如,在实体框架中,当您提出一个不理解如何处理的问题时,当您尝试获取{{1>时,会收到类似“不支持指定方法”的错误来自IEnumerable
的答案。
- 醇>
IQueryable
有两种DBSet<T>
(Where
和IQueryable
)。 有没有办法调用IEnumerable
版本,因为 默认情况下会调用IEnumerable
,而不调用IQueryable
?
班级ToList()
没有Where method on it at all。这两个DBSet<T>
函数来自两个扩展方法Enumerable.Where
和Queryable.Where
。在调用扩展方法之前,可以通过将对象强制转换为Where
来强制它使用Enumerable重载。但请记住,IEnumerable<T>
过滤了问题,Queryable.Where
仅过滤结果。
从服务器请求结果然后将它们扔掉是浪费的,所以我不建议这样做。