如何将这个 SQL 翻译成 LINQ,相关子查询单个 table
How to translate this SQL into LINQ, with correlated subquery single table
原始 SQL 使用单个 table 的相关子查询,是否有可能用单个 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)
它按类型和 select 销售价格大于类型组平均值的产品对产品进行分组。 LINQ 数据源是一个 EFCore DbSet。
尝试以下查询:
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;
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 无法在 IQueryable 上翻译此 LINQ
所以我们使用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
select new { Type = typeGroup.Key, Average = typeGroup.Average(p => p.SalePrice) }
on product.Type equals typeGroup.Type
where product.SalePrice > typeGroup.Average
select product;
原始 SQL 使用单个 table 的相关子查询,是否有可能用单个 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)
它按类型和 select 销售价格大于类型组平均值的产品对产品进行分组。 LINQ 数据源是一个 EFCore DbSet。
尝试以下查询:
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;
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 无法在 IQueryable 上翻译此 LINQ
所以我们使用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
select new { Type = typeGroup.Key, Average = typeGroup.Average(p => p.SalePrice) }
on product.Type equals typeGroup.Type
where product.SalePrice > typeGroup.Average
select product;