如何迭代分组项并进行比较?

时间:2017-11-07 23:52:34

标签: c# group-by linq-to-objects

由于我是Entity Framework的新手,因此我很难使用这种方法。我实际上不知道是否有与EF有关的特殊事项,或者是否存在限制。

我想从我的数据库中对一些记录进行分组,之后,我想迭代这些组,然后迭代每个组上的元素,将它与同一组中的所有其他元素进行比较。

我创建了两个简单的类来说明场景:

public class MyContext : DbContext
{
    public DbSet<MyClass> MyClass { get; set; }
}

public class MyClass
{
    public int Id { get; set; }
    public int Value { get; set; }
}

到目前为止我注入的上下文是:

this.MyContext.MyClass
            .GroupBy(x => x.Value)
            .ToList() // need to materialize here
            .ForEach(grp =>
            {
                // compare each item with all the other
                // items in the current group        
            });

但我不知道如何迭代这些项目,然后与同一组中的其他项目进行比较。

2 个答案:

答案 0 :(得分:1)

使用以下代码,问题变为什么类型grp

this.MyContext.MyClass
  .GroupBy(x => x.Value)
  .ToList() // need to materialize here
  .ForEach(grp =>
  {
    // compare each item with all the other
    // items in the current group        
  });

grp变量的类型为IGrouping<TKey, TElement>。该类型来自IEnumerable<TElement>,因此每个grp都是TElement列表,因此您可以foreach或对所有项目执行任何操作grp。

DotNetFiddle Example

答案 1 :(得分:0)

您的变量grpIGrouping<int, MyClass>。您可以将其视为IEnumerable<MyClass>。例如,您可以获得具有最大ID的项目,如下所示:

this.MyContext.MyClass
    .GroupBy(x => x.Value)
    .ToList() // need to materialize here
    .ForEach(grp =>
    {
         MyClass itemWithMaxId = grp.FirstOrDefault();
         foreach (MyClass item in grp)
         {
             if (item.Id > itemWithMaxId.Id)
             {
                 itemWithMaxId = item;
             }
         }      
    });

但请注意,ForEach方法不返回任何内容,它只对列表的每个元素执行指定的操作。如果您想获得某些内容,例如每个组中ID最大的项目,建议您使用Select提供的Linq方法,如下例所示:

var itemsWithMaxIdByGroup = this.MyContext.MyClass
    .GroupBy(x => x.Value)
    .ToList() // need to materialize here
    .Select(grp =>
    {
         MyClass itemWithMaxId = grp.First();
         foreach (MyClass item in grp.Skip(1))
         {
             if (item.Id > itemWithMaxId.Id)
             {
                 itemWithMaxId = item;
             }
         }  

         return itemWithMaxId;    
    });