如何迭代分组项目并比较它们?

How to Iterate over grouped items and compare them?

由于我是 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        
            });

但我不知道如何遍历项目然后与同一组中的其他项目进行比较。

使用下面的代码,问题变成了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 都是 TElementlist 所以你可以 foreach 或做任何你想做的事grp.

中的项目

DotNetFiddle Example.

您的变量 grp 是一个 IGrouping<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 方法不return 任何东西,它只对列表的每个元素执行指定的操作。如果你想得到一些东西,比如每个组中id最大的item,我建议你使用Linq提供的Select方法,比如这个例子:

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