IQueryable vs IEnumerable: IQueryable是否总是更好和更快?

30 浏览
0 Comments

IQueryable vs IEnumerable: IQueryable是否总是更好和更快?

1. 如果IQueryable接口在服务器上执行查询表达式,而不像IEnumerable那样获取所有记录,为什么不将IQueryable替换为IEnumerable,以便提高速度和效率?\n2. DbSet有两种Where方法(IQueryable和IEnumerable)。有没有办法调用IEnumerable版本,而不是默认调用IQueryable,而不必调用ToList()方法?

0
0 Comments

IQueryable vs IEnumerable: IQueryable是否总是更好和更快?

IQueryable和IEnumerable代表两个不同的东西。将IQueryable视为一个“问题”,它本身没有任何结果。IEnumerable是一个“答案”,它只有与之相关的数据,但你无法知道生成这些数据的方式。

并不是说IQueryable“更快”,它只是允许你将过滤和投影放在你向SQL服务器提出的“问题”中,并让它只返回需要的答案(通过调用.ToList()或类似的方法返回一个IEnumerable)。如果只使用IEnumerable,你只能问“给我你所知道的一切”,然后在得到的答案上进行过滤和投影。这就是为什么IQueryable被认为更快,因为需要处理的数据要少得多,因为你能够向服务器提出更具体的问题。

IQueryable没有完全取代IEnumerable的原因是因为你要问一个问题的对象必须能够理解你提出的问题。要能够解析出你可能问它进行过滤或投影的每一个可能的事物需要很多工作,因此大多数实现都限制自己只能回答它们知道自己需要回答的常见问题。例如,在Entity Framework中,当你问一个它不理解如何处理的问题时,尝试从IQueryable获取一个IEnumerable(一个答案)时,你会得到一个类似于“指定的方法不受支持”的错误。

DBSet有两种版本的Where(IQueryable和IEnumerable)。是否有一种方法可以调用IEnumerable版本,而不是默认调用IQueryable,而不调用ToList()?

DBSet类根本没有Where方法。这两个Where函数来自两个扩展方法,Enumerable.Where和Queryable.Where。你可以在调用扩展方法之前将对象强制转换为IEnumerable来强制使用Enumerable的重载。然而,请记住,Queryable.Where过滤问题,Enumerable.Where仅过滤结果。从服务器上获取结果然后将其丢弃是很浪费的,所以我不建议这样做。根据你的例子(问题和答案),我理解到在将其转换为一个IEnumerable列表以获得期望的答案之前,IQueryable是没有用的。所以在我处理IQueryable相关的所有事情之后,我将其转换为一个Enumerable列表并获得结果,对吗?

0