B12*_*ter 15 c# linq join where .net-core
情况:假设我们正在执行连接两个内存列表的LINQ查询(因此不涉及DbSets或SQL查询生成),并且此查询也有一个where子句.这where仅过滤原始集合中包含的属性(from查询的一部分).
问题: linq查询解释器是否优化了这个查询,因为它首先在执行where之前执行join,而不管我是where在之前还是之后写的join? - 所以它不必在以后不包含的元素上执行连接.
示例:例如,我有一个categories列表,我想要与products列表一起加入.但是,我只对categorywith ID1 感兴趣.无论我是否编写,linq解释器内部执行完全相同的操作:
from category in categories
join prod in products on category.ID equals prod.CategoryID
where category.ID == 1 // <------ below join
select new { Category = category.Name, Product = prod.Name };
Run Code Online (Sandbox Code Playgroud)
要么
from category in categories
where category.ID == 1 // <------ above join
join prod in products on category.ID equals prod.CategoryID
select new { Category = category.Name, Product = prod.Name };
Run Code Online (Sandbox Code Playgroud)
以前的研究:我已经看到了这个问题但OP作者表示他/她的问题仅针对生成SQL的非内存情况.我对LINQ在内存中的两个列表上执行连接感兴趣.
更新:这不是"链式linq查询的顺序执行"问题的公告,因为引用的问题明确指的是dbset,我的问题明确地解决了非db方案.(此外,虽然类似,但我不是在这里询问基于导航属性的内容,而是关于"连接".)
Update2:虽然非常相似,但这也不是"使用LINQ时谓词的顺序是否重要"的公告?因为我明确询问内存情况,我无法看到引用的问题明确解决这种情况.此外,问题有点陈旧,我实际上对.NET Core(2012年不存在)中的linq感兴趣,所以我更新了这个问题的标签以反映第二点.
请注意:有了这个问题,我的目标是linq查询解释器是否在某种程度上在后台优化了这个查询,我希望得到一个文档或源代码的参考,以显示如何通过linq完成.我对诸如"它无关紧要因为两个查询的性能大致相同"之类的答案不感兴趣.
LINQ查询语法将编译为方法链.有关详细信息,请参阅此问题.
第一个LINQ查询将编译为以下方法链:
categories
.Join(
products,
category => category.ID,
prod => prod.CategoryID,
(category, prod) => new { category, prod })
.Where(t => t.category.ID == 1)
.Select(t => new { Category = t.category.Name, Product = t.prod.Name });
Run Code Online (Sandbox Code Playgroud)
第二个:
categories
.Where(category => category.ID == 1)
.Join(
products,
category => category.ID,
prod => prod.CategoryID,
(category, prod) => new { Category = category.Name, Product = prod.Name });
Run Code Online (Sandbox Code Playgroud)
如您所见,第二个查询将导致更少的分配(请注意第一个查询中只有一个匿名类型vs 2,并注意在执行查询时将创建多少个匿名类型的实例).
此外,很明显第一个查询将比第二个(已经过滤的)数据执行更多数据的连接操作.
在LINQ到对象查询的情况下,不会有额外的查询优化.
所以第二个版本更可取.
| 归档时间: |
|
| 查看次数: |
445 次 |
| 最近记录: |