Linq用GroupBy表达

时间:2014-10-03 08:09:35

标签: c# linq entity-framework

我有一个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>但我收到此错误:

  

无法转换类型&#39;分组[System.Guid,ConsoleApplication1 + DocumentGroup]&#39;输入&#39; DocumentGroup&#39;。

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; }
}

2 个答案:

答案 0 :(得分:4)

当您使用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();

答案 1 :(得分:0)

在执行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
    }
}
  

但我必须有组表达式来过滤它

我假设您希望在所有DocumentGroup中获得所有唯一的DocumentType,然后Salman22回答您正在寻找的内容。

在这种情况下,您也可以使用Distinct。如果你正在使用linq实体,你可以拥有。

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();