【发布时间】:2020-07-14 16:55:05
【问题描述】:
我正在使用 Microsoft.EntityFrameworkCore 版本 3.1.3:
我有以下对象:
public class OrganisationMention
{
public int Id { get; set; }
public int OrganisationId { get; set; }
public Organisation Organisation { get; set; }
public int PublicationId { get; set; }
public Publication Publication { get; set; }
public int LocationId { get; set; }
public Location Location { get; set; }
public int PracticeAreaId { get; set; }
public PracticeArea PracticeArea { get; set; }
public int Count { get; set; }
public int MarketAverage { get; set; }
}
我想按 Publication\Location\PracticeArea 聚合一个 OrganisationMentions 列表,以获取一个具有计数总和的相关组织提及对象列表,如下所示:
public class RelatedOrganisationMentions
{
public int PublicationId { get; set; }
public Publication Publication { get; set; }
public int LocationId { get; set; }
public Location Location { get; set; }
public int PracticeAreaId { get; set; }
public PracticeArea PracticeArea { get; set; }
public int Count { get; set; }
public int MarketAverage { get; set; }
}
如果我使用以下 LINQ 查询,我会收到与 Publication\Location\PracticeArea 对象的投影有关的可怕错误。如果我省略它们,则查询返回正常。但是,我确实希望它们回到聚合结果中,并且可以保证如果 PublicationId 相同,每个 Publication 对象都是同一个实体:
IQueryable<RelatedOrganisationMentions> relatedOrganisationMentions = collection
.GroupBy(m => new { m.LocationId, m.PublicationId, m.PracticeAreaId })
.Select(am => new RelatedOrganisationMentions
{
PracticeArea = am.First().PracticeArea, //Causes long and horrid error
Location = am.First().Location, //Causes long and horrid error
Publication = am.First().Publication, //Causes long and horrid error
PracticeAreaId = am.Key.PracticeAreaId,
PublicationId = am.Key.PublicationId,
LocationId = am.Key.LocationId,
Count = am.Sum(x => x.Count)
})
.OrderBy(r => r.Publication.Description)
.ThenBy(r => r.PracticeArea.Description);
return await relatedOrganisationMentions.ToListAsync(token).ConfigureAwait(false);
请问如何按多列分组并保留聚合投影中的对象?
错误
System.InvalidOperationException:LINQ 表达式 '(GroupByShaperExpression:KeySelector:新{ LocationId = EntityMaterializerSource.TryReadValue(grouping.Key, 0, 属性: OrganisationMention.LocationId (int) 必需的 FK 索引), PublicationId = EntityMaterializerSource.TryReadValue(grouping.Key, 1, 属性: OrganisationMention.PublicationId (int) 必需的 FK 索引), PracticeAreaId = EntityMaterializerSource.TryReadValue(grouping.Key, 2, 属性: OrganisationMention.PracticeAreaId (int) 必需的 FK 索引) }, 元素选择器:(实体形状表达式: 实体类型:组织提及 值缓冲区表达式: (ProjectionBindingExpression:EmptyProjectionMember) IsNullable: 假 ) ) .First()' 无法翻译。要么以可翻译的形式重写查询,要么显式切换到客户端评估 通过插入对 AsEnumerable()、AsAsyncEnumerable() 的调用, ToList() 或 ToListAsync()。看 https://go.microsoft.com/fwlink/?linkid=2101038 了解更多信息。 在
更新 1:看起来这是 efcore 3.1 的一个已知问题,现在正在寻找可能的解决方法。
【问题讨论】:
-
GroupByEF 核心 3 中的支持仅限于最简单的情况(按原始属性分组,只选择关键属性 + 聚合)。对于其他任何事情,您都必须找到解决方法。不仅仅是First不可翻译(尽管它不是),无论你尝试什么,整个GroupBy都会失败。