【问题标题】:Using linq to calculate rating average in EF Core使用 linq 计算 EF Core 中的平均评分
【发布时间】:2021-12-23 11:16:12
【问题描述】:

用户可以按城市、品牌、服务类型和评级搜索公司。我已经开发了这样一个查询,但在评分部分出现错误。错误信息如下:

LINQ 表达式 'DbSet 。加入( 外部:数据库集, 内部:f => f.Id, outerKeySelector: c => c.FirmId, innerKeySelector: (f, c) => new TransparentIdentifier( 外部 = f, 内部 = c )) 。通过...分组( 来源:ti => ti.Outer, 键选择器:ti => 新 { 公司 = ti.Outer, 评级 = ti.Inner.Rate })' 无法翻译。要么以可翻译的形式重写查询,要么显式切换到客户端评估 通过插入对 AsEnumerable()、AsAsyncEnumerable() 的调用, ToList() 或 ToListAsync()。看 https://go.microsoft.com/fwlink/?linkid=2101038 了解更多信息。

我在添加评分部分后遇到了这个错误。我怎样才能解决这个问题?我认为以这种方式提取数据不会有效。我应该如何开发这个地方?我还与您分享我用于查询的代码。

public async Task<IEnumerable<Firm>> GetFirmsForCustomerSearch(int cityId, int brandId, int serviceTypeId, int rate)
        {
           var query = from firms in AracsalContext.Firm select firms;
            
            if (brandId > 0)
                query = from firms in query
                        join firmBrands in AracsalContext.Firmbrand on new { f1 = firms.Id, f2 = brandId } equals new { f1 = firmBrands.FirmId, f2 = firmBrands.BrandId }
                        select firms;

            if (serviceTypeId > 0)
                query = from firms in query
                        join firmServices in AracsalContext.Firmservice on new { f1 = firms.Id, f2 = serviceTypeId } equals new { f1 = firmServices.FirmId, f2 = firmServices.ServiceId }
                        select firms;

            if (cityId > 0)
                query = from firms in query
                        where firms.CityId == cityId
                        select firms;

            if (rate > 0)
            {
                query = from firms in query
                        join comments in AracsalContext.Comment on firms.Id equals comments.FirmId
                        group new
                        {
                            firm = firms,
                            rating = comments.Rate
                        } by firms into g
                        where g.Average(r => r.rating) > rate
                        select g.Key;
            }


            var result = await query.ToListAsync();
            return result;
        }

非常感谢。 斋月

【问题讨论】:

    标签: c# performance linq asp.net-core query-optimization


    【解决方案1】:

    SQL 中的分组有局限性——您只能返回分组键和聚合结果。要返回整个记录,您必须加入原始查询增益。

    if (rate > 0)
    {
        filteredByRate = 
            from firms in query
            join comments in AracsalContext.Comment on firms.Id equals comments.FirmId
            group new
            {
                rating = comments.Rate
            } by new { firms.Id } into g
            where g.Average(r => r.rating) > rate
            select g.Key;
    
        query = 
            from films in query
            join f in filteredByRate on films.Id equals f.Id
            select films;
    }
    

    【讨论】:

    • 报错信息中说可能有限制问题。我想你是对的。您的建议也解决了问题,谢谢。那么有没有办法在一个查询中聚合这些连接?这样做会导致性能问题吗?
    • 应该没有性能问题,将查询分解为可理解的小部分是一种正常的方式。
    【解决方案2】:

    您需要按一些 Id 进行分组,例如公司。Id

    query = from firms in query
                            join comments in AracsalContext.Comment on firms.Id equals comments.FirmId
                            group new
                            {
                                firm = firms,
                                rating = comments.Rate
                            } by firms.Id into g
                            where g.Average(r => r.rating) > rate
                            select g.Key;
    

    【讨论】:

    • 当我这样做时,返回值是 int。而我希望返回值是坚定的。这就是我这样做的原因
    猜你喜欢
    • 2013-07-31
    • 2017-12-03
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    • 2017-10-11
    • 1970-01-01
    相关资源
    最近更新 更多