[英]LINQ to Entities - Entity Framework
我希望更好地了解何时应该使用IEnumerable
和LINQ to Entities的IQueryable
。
通过对数据库的真正基本调用, IQueryable
更快了,但是何时需要考虑在其位置使用IEnumerable
?
IEnumerable
最优于IQueryable
最佳位置在哪里?
基本上,IQueryable由查询提供程序(例如数据库)执行,并且某些操作不能或不应该由数据库执行。 例如,如果您要使用从数据库中获得的值来调用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();
从EF的角度来看,关于IQueryable与IEnumerable的性能,最重要的是,您应始终尝试使用IQueryable过滤数据,以获取尽可能少的数据以转换为IEnumerable。 AsEnumerable
调用的主要作用是告诉数据库“立即将过滤后的数据提供给我”,如果不进行过滤,则所有内容都将被提取到内存中,即使您可能不需要数据。
IEnumerable
表示一系列元素,您逐一枚举直到找到所需的答案,因此,例如,如果我想要所有属性大于10的实体,则需要依次遍历每个实体并仅返回那些匹配。 为了做到这一点,将数据库表的每一行都拉到内存中可能不是一个好主意。
另一方面, IQueryable
表示一组元素,可以将诸如过滤之类的操作推迟到基础数据源,因此在过滤情况下,如果我要在自定义数据源之上实现IQueryable
(或使用LINQ to Entities! ),那么我可以对数据源(例如数据库)进行过滤/分组等艰苦的工作。
IQueryable
的主要缺点是实现它非常困难-查询被构造为Expression树,您必须将其解析为实现者才能解析查询。 如果您不打算编写提供程序,那么这不会伤害您。
IQueryable的另一个值得注意的方面(尽管这实际上只是将处理传递给可能对世界做出不同假设的另一个系统的一般警告),您可能会发现像字符串比较这样的事情在源系统中受支持,而不是由使用者实现它们的方式,例如,如果源数据库不区分大小写,但.NET中的默认比较是区分大小写的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.