在 .NET Core 中使用 GroupBy
Posted
技术标签:
【中文标题】在 .NET Core 中使用 GroupBy【英文标题】:Using GroupBy in .NET Core 【发布时间】:2021-03-12 13:22:39 【问题描述】:我需要对我的查询结果进行分组。主要问题是当我使用 GroupBy 时,GroupBy 语句的返回类型是 IGrouping
,这与我的方法的返回类型 List<MyViewModel>
不同。所以这两种类型不匹配。现在第一个选项是更改我的方法的返回类型。在这种情况下,如何在视图层(Razor 页面的 html 部分)中访问 ViewModel 的属性?
在不改变我的方法返回类型的情况下使用 GroupBy 有什么选择吗?
public List<MultimediaViewModel> Search(MultimediaSearchModel searchModel)
var query = _hContext.Multimedias.Include(x => x.Ceremony)
.Select(g => new MultimediaViewModel
Id = g.Id,
Title = g.Title,
CeremonyId = g.CeremonyId,
Ceremony = g.Ceremony.Title,
FileAddress = g.FileAddress,
).AsEnumerable().GroupBy(g => g.CeremonyId).ToList();
if (!string.IsNullOrWhiteSpace(searchModel.Title))
query = query.Where(g => g.Title.Contains(searchModel.Title)).ToList();
if (searchModel.CeremonyId != 0)
query = query.Where(g => g.Key == searchModel.CeremonyId).ToList();
return query;
由于方法返回类型和Group by返回类型之间的差异,上面的代码不起作用。
【问题讨论】:
无法自动执行此操作。在 GroupBy 之后,您只有IGrouping
结果,稍后应重新映射。按 CeremonyId 分组有什么意义?在MultimediaViewModel
中应该有适当的理由
对于每个不同的仪式 ID,可能有多个多媒体。你要哪一个?
对于每个仪式 ID,可能有多个多媒体。所以当我们要保存每一个多媒体项时,我们应该通过 CeremonyId 将它分配给仪式,CeremonyId 是多媒体模型中 Ceremony 模型的外键。
GroupBy
有几个重载,其中一个返回 IEnumerable<TResult>
。使用提供所需返回类型的重载之一。
@Amin,最好用MultimediaViewModel
定义更新问题。
【参考方案1】:
在不完全了解您的业务需求的情况下,我可以提供 2 种方法来解决此问题
在方法外使用GroupBy,使用Search方法返回一个列表,然后使用GroupBy对其进行分组
如果你只需要返回一个特定CeremonyId的MultimediaViewModel列表,你可以搜索IGrouping的列表得到一个特定的子列表
public List<MultimediaViewModel> Search(MultimediaSearchModel searchModel)
var query = _hContext.Multimedias.Include(x => x.Ceremony).Select(g => new MultimediaViewModel
Id = g.Id,
Title = g.Title,
CeremonyId = g.CeremonyId,
Ceremony = g.Ceremony.Title,
FileAddress = g.FileAddress
).GroupBy(g => g.CeremonyId).ToList();
return query.FirstOrDefault(g=>g.Key==searchModel.CeremonyId).ToList();
//you can just use Where to find all of the MultimediaViewModel instead of using GroupBy
编辑 可能将结果作为字典返回
public Dictionary<string, List<MultimediaViewModel>> Search(MultimediaSearchModel searchModel)
var query = _hContext.Multimedias.Include(x => x.Ceremony).Select(g => new MultimediaViewModel
Id = g.Id,
Title = g.Title,
CeremonyId = g.CeremonyId,
Ceremony = g.Ceremony.Title,
FileAddress = g.FileAddress
).GroupBy(g => g.CeremonyId).ToList();
return query.ToDictionary(k => k.Key, v => v.ToList());
【讨论】:
感谢迈克尔的回复。但让我解释一下我的问题。如果我的 searchModel 参数为空,我需要列出所有仪式。所以当页面加载时,我们应该有一个多媒体仪式专辑列表。我们已经有了这个列表,但每个多媒体项目都会重复仪式。我想更改此 saerch 方法以根据其仪式向我返回多媒体项目。例如假设我们有 3 个仪式。对于每个仪式,我们有 4 个多媒体项目。现在列表向我们显示了 12 行,而预计有 3 行。 请您建议如何使用 Group By 外部方法? 根据您的回答,我认为您需要将 CeremonyId 的字典返回到 MultimediaViewModel 的列表中,我已经用一种方法编辑了我的答案 我已根据您的评论编辑了我的方法,但收到以下错误:错误 CS0029 无法隐式转换类型 'System.Collections.Generic.Dictionary以上是关于在 .NET Core 中使用 GroupBy的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用AutoMapper进行实体映射
如何使用 EF Core 在 ASP.NET Core 中取消应用迁移