带有GroupBy的Linq表达式
本文关键字:表达式 Linq GroupBy 带有 | 更新日期: 2023-09-27 18:25:28
我有一个linq表达式,我想将其分组并转换为硬类型List<DocumentGroup>
此linq查询工作正常:
var DocumentGroups = (from dt in DocumentTypes
let dg = dt.DocumentGroup
select new DocumentGroup(){
Name = dg.Namn,
Id = dg.Id
}).GroupBy(group => group.Id).ToList();
现在我想做同样的查询并将其转换为List<DocumentGroup>
,但我收到了以下错误:
无法将"Grouping[System.Guid,ConsoleApplication1+DocumentGroup]"类型的对象强制转换为"DocumentGroup"类型。
List<DocumentGroup> DocumentGroups = (from dt in DocumentTypes
let dg = dt.DocumentGroup
select new DocumentGroup(){
Name = dg.Namn,
Id = dg.Id
}).GroupBy(group => group.Id).Cast<DocumentGroup>.ToList();
如果我从linq表达式中删除.GroupBy(group => group.Id)
,它可以正常工作,但我需要组表达式来过滤掉它。我怎样才能做到这一点?
DocumentGroup类
public class DocumentGroup
{
public string Name { get; set; }
public Guid Id { get; set; }
}
当您使用GroupBy
时,您会得到组。因此,将一个组投射到单个项目将失败。
如果你只想删除重复项,那么你可以从每组中选择第一个项目:
var DocumentGroups = (from dt in DocumentTypes
let dg = dt.DocumentGroup
select new DocumentGroup()
{
Name = dg.Namn,
Id = dg.Id
}).GroupBy(group => group.Id)
.Select(g => g.First())
.ToList();
在执行GroupBy
之前,您有一个DocumentGroup
(类似于一维数组)列表
1 Name1 <record 1 of DocumentGroup>
1 Name2 <record 2 of DocumentGroup>
1 Name3 <record 3 of DocumentGroup>
2 Name4 <record 4 of DocumentGroup>
3 Name5 <record 5 of DocumentGroup>
完成GroupBy
后,您将获得IGrouping<int, DocumentGroup>
(类似于二维阵列)的列表
1 1 Name1 --|
1 Name2 -- <record 1 of IGrouping<int, DocumentGroup>
1 Name3 --|
2 2 Name4 <record 2 of IGrouping<int, DocumentGroup>>
3 3 Name5 <record 3 of IGrouping<int, DocumentGroup>>
因此,要获得DocumentGroup
,您需要首先从Grouping
项目访问,然后获得DocumentGroup
,例如:
var groupOfDocumentGroups = /* omitted code */
select new DocumentGroup() { Name = dg.Namn, Id = dg.Id })
.GroupBy(group => group.Id)
.ToList();
foreach(var groupItem in groupOfDocumentGroups)
{
// groupItem type is IGrouping<int, DocumentGroup>
// groupItem has `Key` property which is an integer of the Id.
// groupItem is also a collection that you can do enumeration.
foreach(var item in groupItem)
{
// there you go, item type is DocumentGroup
}
}
但我必须有组表达式才能过滤掉
我假设您想在所有DocumentType
中获得所有唯一的DocumentGroup
,那么Salman22
的答案就是您想要的。
在这种情况下,您也可以使用Distinct
。如果您正在使用linq-to实体,您可以只使用。
var documentGroups = context.DocumentTypes
.Select(x => x.DocumentGroup)
.Distinct()
.ToList();
如果您使用linq来处理对象,那么可以先实现IEqualityComparer<DocumentGroup>
。
class DocumentGroupComparer : IEqualityComparer<DocumentGroup>
{
public bool Equals(DocumentGroupx, DocumentGroupy)
{
return x.Id == y.Id;
}
public int GetHashCode(DocumentGroup obj)
{
return obj.Id.GetHashCode();
}
}
var documentGroups = DocumentTypes
.Select(x => x.DocumentGroup)
.Distinct(new DocumentGroupComparer())
.ToList();