我希望更好地了解何时应该使用IEnumerable
LINQ IQueryable
to Entities。
对数据库进行真正基本的调用会IQueryable
更快,但是我什么时候需要考虑使用 anIEnumerable
来代替它?
哪里是IEnumerable
最优的IQueryable
??
我希望更好地了解何时应该使用IEnumerable
LINQ IQueryable
to Entities。
对数据库进行真正基本的调用会IQueryable
更快,但是我什么时候需要考虑使用 anIEnumerable
来代替它?
哪里是IEnumerable
最优的IQueryable
??
基本上,IQueryables 由查询提供程序(例如数据库)执行,并且某些操作不能或不应该由数据库完成。例如,如果您想使用从数据库中获得的值调用 C# 函数(这里作为示例,名称正确大写),您可以尝试类似的方法;
db.Users.Select(x => Capitalize(x.Name)) // Tries to make the db call Capitalize.
.ToList();
由于在Select
IQueryable 上执行,并且底层数据库不知道您的Capitalize
函数,因此查询将失败。相反,您可以做的是从数据库中获取正确的数据并将 IQueryable 转换为 IEnumerable (这基本上只是一种遍历内存中集合的方法)以在本地内存中执行其余操作,如下所示;
db.Users.Select(x => x.Name) // Gets only the name from the database
.AsEnumerable() // Do the rest of the operations in memory
.Select(x => Capitalize(x)) // Capitalize in memory
.ToList();
The most important thing when it comes to performance of IQueryable vs. IEnumerable from the side of EF, is that you should always try to filter the data using an IQueryable to get as little data as possible to convert to an IEnumerable. What the AsEnumerable
call basically does is to tell the database "give me the data as it is filtered now", and if you didn't filter it, you'll get everything fetched to memory, even data you may not need.
IEnumerable
表示您一个一个枚举的元素序列,直到找到所需的答案,例如,如果我想要所有属性大于 10 的实体,我需要依次遍历每个元素并只返回那些那匹配。将数据库表的每一行都拉入内存以执行此操作可能不是一个好主意。
IQueryable
另一方面表示一组元素,在这些元素上,过滤等操作可以推迟到底层数据源,所以在过滤的情况下,如果我要IQueryable
在自定义数据源之上实现(或使用 LINQ to Entities!),那么我可以将过滤/分组等工作交给数据源(例如数据库)。
主要的缺点IQueryable
是实现它非常困难 - 查询被构造为表达式树,作为实现者,您必须解析它才能解析查询。如果您不打算编写提供程序,那么这不会伤害您。
值得了解的 IQueryable 的另一个方面(尽管这实际上只是关于将处理传递给可能对世界做出不同假设的另一个系统的一般警告)是,您可能会发现字符串比较之类的事情以它们的方式工作在源系统中支持,而不是以消费者实现它们的方式,例如,如果您的源数据库不区分大小写,但您在 .NET 中的默认比较是区分大小写的。