如何把这个SQL翻译成LINQ,并带有相关的子查询单表

2 人不认可

原始SQL对单个表使用相关的子查询,有没有可能用单个LINQ查询来翻译?

SELECT * From dbo.Products AS P1
WHERE SalePrice > (SELECT AVG(SalePrice)
                   FROM dbo.Products AS P2
                   WHERE P1.Type = P2.Type GROUP BY Type)

它按类型对产品进行分组,并选择SalePrice大于类型组平均值的产品。LINQ数据源是一个EFCore DbSet。

c#
sql-server
linq
entity-framework-core
KumimaZ
KumimaZ
发布于 2022-04-20
2 个回答
Svyatoslav Danyliv
Svyatoslav Danyliv
发布于 2022-05-03
已采纳
0 人赞同

试试下面的查询。

var products = context.Products;
var grouped = 
    from p in products
    group p by p.Type into g
    select new 
        Type = g.Key,
        Average = g.Average(x => x.SalePrice)
var query = 
    from p in products
    join g in grouped on p.Type equals g.Type
    where p.SalePrice > g.Average
    select p;
这确实有效,但它使用了两个LINQ查询,有没有办法将它们合并成一个?
不要这样做。在最后将只执行最新的组合查询。否则LINQ查询会变得一团糟。
你知道如何在使用单线程时防止将所有数据带入内存吗? 请看我的答案。
正如我之前提到的,不要把所有东西都放在单一的查询中。它不具有可读性,而且你可能会像你自己的 答案 那样犯错。
现在同意了,只是想试一试,用单线程。总之,再次感谢你的帮助,你的方法确实更好。
KumimaZ
KumimaZ
发布于 2022-05-03
0 人赞同
from product in products.AsEnumerable()
group product by product.Type into typeGroup
from product in typeGroup
where product.SalePrice > typeGroup.Average(product => product.SalePrice)
select product;

注意:从开始的SQL中的第二个产品与第一个不同。

EF Core 6无法翻译这个LINQ on IQueryable

所以我们使用AsEnumerable(),它将所有的产品数据带入内存。所以,也许原始的SQL应该是更好的。

像另一个答案那样把它分成两个查询,可以解决问题,并使它更有可读性。

原因是IQueryable.GroupBy()不能成为EF 6的最终操作符,这计划在EF Core 7中得到改进。

为了防止GroupBy()成为最终运算符。解决办法是

var query =
    from product in products
    join typeGroup in
from product in products
        group product by product.Type into typeGroup