one*_*mer 7 linq performance linq-to-entities entity-framework
我正在寻找这些LINQ表达式的确认/澄清:
var context = new SomeCustomDbContext()
// LINQ to Entities?
var items = context.CustomItems.OrderBy(i => i.Property).ToList();
// LINQ to Objects?
var items2 = context.CustomItems.ToList().OrderBy(i => i.Property);
Run Code Online (Sandbox Code Playgroud)
(Q1)我是否认为第一种方法是LINQ to EntitiesEF构建一个更具体的SQL语句来传递,将订购工作放在数据库上?
(Q2)第二种方法LINQ to Objects是LINQ ToList()在订购之前将整个集合拖入内存(枚举?),从而在服务器端(本例中为Web服务器)留下负担?
如果是这种情况,我可以很快看到L2E有利的情况(例如,在将它们拉入内存之前过滤/修剪集合).
(Q3)但是,我应该注意还有其他任何细节/权衡,或者"方法2"可能比第一种方法更有利的时候?
更新:
假设我们没有使用EntityFramework,只要底层存储库/数据源实现IQueryable<T>正确,这仍然是正确的?如果不是这两个语句都导致LINQ to Objects内存中的操作?
你是正确的,调用ToList()迫使linq-to-entities评估并将结果作为列表返回.正如您所怀疑的那样,这可能会产生巨大的性能影响.
在某些情况下,linq-to-entities无法弄清楚如何解析看起来像一个非常简单的查询(如Where(x => SomeFunction(x))).在这些情况下,您通常别无选择ToList(),只能在内存中调用和操作集合.
为了回应您的更新:
ToList()总是迫使一切都在它前面立即评估,而不是延迟执行.举个例子:
someEnumerable.Take(10).ToList();
Run Code Online (Sandbox Code Playgroud)
VS
someEnumerable.ToList().Take(10);
Run Code Online (Sandbox Code Playgroud)
在第二个示例中,someEnumerable必须在获取前10个元素之前执行任何延迟的工作.如果someEnumerable正在做一些劳动密集型工作(比如从磁盘读取文件Directory.EnumerateFiles()),这可能会产生非常实际的性能影响.