使用 linq 计算 EF Core 中的平均评分
Posted
技术标签:
【中文标题】使用 linq 计算 EF Core 中的平均评分【英文标题】:Using linq to calculate rating average in 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;
非常感谢。 斋月
【问题讨论】:
【参考方案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。而我希望返回值是坚定的。这就是我这样做的原因以上是关于使用 linq 计算 EF Core 中的平均评分的主要内容,如果未能解决你的问题,请参考以下文章