在带有 group by 的 LINQ 查询中使用 DefaultIfEmpty() 时出错

Errors using DefaultIfEmpty() in LINQ query with group by

我有以下 LINQ(到 SQL 服务器)查询:

var railcarsByProduct = await (from r in DbContext.Railcars
                               let p = DbContext.ProductAliases
                                   .Where(pa => pa.Product.Company.CompanyCode == companyCode && pa.Alias == r.Product)
                                   .Select(pa => pa.Product.Name)
                                   .FirstOrDefault()
                               where r.Facility.Company.CompanyCode == companyCode && r.Departure == null
                               group r by p into productGroup
                               select new { Product = productGroup.Key, Count = productGroup.Count() }
                              ).ToListAsync();

这工作正常。但是,ProductAliases 子查询有可能 return 为空。在那种情况下,我想默认为 r.Product.

我尝试将 DefaultIfEmpty() 添加到子查询。

var railcarsByProduct = await (from r in DbContext.Railcars
                               let p = DbContext.ProductAliases
                                   .Where(pa => pa.Product.Company.CompanyCode == companyCode && pa.Alias == r.Product)
                                   .Select(pa => pa.Product.Name)
                                   .DefaultIfEmpty(r.Product)
                                   .FirstOrDefault()
                               where r.Facility.Company.CompanyCode == companyCode && r.Departure == null
                               group r by p into productGroup
                               select new { Product = productGroup.Key, Count = productGroup.Count() }
                              ).ToListAsync();

但这给出了一个错误。

'The LINQ expression 'DbSet() .Where(pa => pa.Product.Company.CompanyCode == __companyCode_0 && pa.Alias == r.Outer.Outer.Product) .Select(pa => pa.Product.Name) .DefaultIfEmpty(r.Outer.Outer.Product)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'.

接下来,我尝试在 group by 子句中处理 null 情况。

var railcarsByProduct = await (from r in DbContext.Railcars
                               let p = DbContext.ProductAliases
                                   .Where(pa => pa.Product.Company.CompanyCode == companyCode && pa.Alias == r.Product)
                                   .Select(pa => pa.Product.Name)
                                   .FirstOrDefault()
                               where r.Facility.Company.CompanyCode == companyCode && r.Departure == null
                               group r by p ?? r.Product into productGroup
                               select new { Product = productGroup.Key, Count = productGroup.Count() }
                              ).ToListAsync();

但这也给出了完全相同的错误。

我知道可以只删除所有行,然后将它们分组到 C# 代码中。但是有没有人看到我不需要这样做的方法?

尝试使用类似下面的内容。

var railcarsByProduct = await (from r in DbContext.Railcars
                               let p = DbContext.ProductAliases
                                   .Where(pa => pa.Product.Company.CompanyCode == companyCode && pa.Alias == r.Product)
                                   .Select(pa => pa.Product.Name)
                                   .FirstOrDefault() ?? r.Product
                               where r.Facility.Company.CompanyCode == companyCode && r.Departure == null
                               group r by p into productGroup
                               select new { Product = productGroup.Key, Count = productGroup.Count() }
                              ).ToListAsync();

不确定它是否会起作用,但我知道 DefaultIfEmpty 很奇怪,或者过去 Entity Framework 很奇怪。

尝试以下查询:

var query = 
    from r in DbContext.Railcars
    from p in DbContext.ProductAliases
        .Where(pa => pa.Product.Company.CompanyCode == companyCode && pa.Alias == r.Product)
        .Select(pa => pa.Product.Name)
        .Take(1)
        .DefaultIfEmpty()
    where r.Facility.Company.CompanyCode == companyCode && r.Departure == null
    group r by p ?? r.Product into productGroup
    select new 
    { 
        Product = productGroup.Key, 
        Count = productGroup.Count() 
    };