'How to translate this SQL into LINQ, with correlated subquery single table

The raw SQL uses correlated subquery for single table, any possibility to translate this with single LINQ Query?

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

it groups products by type and select the product whose SalePrice is greater than type group average. LINQ data source is a EFCore DbSet.



Solution 1:[1]

Try the following query:

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;

Solution 2:[2]

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;

Attention: the product in second from beginning SQL is different from the first.

EF Core 6 could not translate this LINQ on IQueryable

So we use AsEnumerable(), and it takes all product data into memory. So maybe the raw SQL one should be better.

Splitting it into two query like another answer will solve the problem and make it more readable.

The reason is IQueryable.GroupBy() can't be the final operator for EF 6, which is planned to be improved with EF Core 7.

To prevent GroupBy() being the final operator. The solution is:

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;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 KumimaZ
Solution 2 marc_s