如何使用Linq在每个组中获得第一条记录

Ari*_*ian 123 c# linq linq-to-entities c#-4.0

考虑以下记录:

   Id          F1            F2             F3 
 -------------------------------------------------
   1           Nima          1990           10
   2           Nima          1990           11
   3           Nima          2000           12
   4           John          2001           1
   5           John          2002           2 
   6           Sara          2010           4
Run Code Online (Sandbox Code Playgroud)

我想根据F1字段进行分组并排序依据Id并从类似于这些记录的组的第一个记录中获取所有字段:

   Id          F1            F2             F3 
 -------------------------------------------------
   1           Nima          1990           10
   4           John          2001           1
   6           Sara          2010           4
Run Code Online (Sandbox Code Playgroud)

我怎么能用linq做到这一点?

Kin*_*ing 161

var result = input.GroupBy(x=>x.F1,(key,g)=>g.OrderBy(e=>e.F2).First());
Run Code Online (Sandbox Code Playgroud)

  • 您应该将`.first()`替换为`.FirstOrDefault()`,否则您将获得异常:`方法'First'只能用作最终查询操作.请考虑在此实例中使用方法'FirstOrDefault' (11认同)
  • @NikolayKostov我知道这一点,但我认为这里的LINQ用作LINQ到对象,而不是LINQ到实体,所以我们可以安全地使用`.first()`.OP的问题看起来真的只是关心linq-to-object,尽管他也用"linq-to-entities"标记了这个问题(不确定他是否明白这是什么). (4认同)
  • 这向我展示了使用Fluent语法的方式.[GroupBy的重载](http://msdn.microsoft.com/en-us/library/vstudio/system.linq.enumerable.groupby(v = vs.100).aspx)似乎给你很多力量 - 一个添加到长长的学习列表! (2认同)

Ali*_*eza 121

    var res = from element in list
              group element by element.F1
                  into groups
                  select groups.OrderBy(p => p.F2).First();
Run Code Online (Sandbox Code Playgroud)

  • 很高兴我找到了这个.我收到错误消息"方法'First'只能用作最终查询操作.请考虑在此实例中使用'FirstOrDefault'方法." 从你的例子.在查询将myResult.ToList()传递给方法之后,我才对列表执行操作.使用FirstOrDefault解决了它 (3认同)

Sta*_*eas 7

@Alireza的awnser是完全正确的,但你必须注意到使用这段代码

var res = from element in list
          group element by element.F1
              into groups
              select groups.OrderBy(p => p.F2).First();
Run Code Online (Sandbox Code Playgroud)

这是与此代码相似的,因为您对列表进行排序然后进行分组,以便获得第一行组

var res = (from element in list)
          .OrderBy(x => x.F2)
          .GroupBy(x => x.F1)
          .Select()
Run Code Online (Sandbox Code Playgroud)

现在,如果你想做一些更复杂的事情,比如采用相同的分组结果,但是拿F2的第一个元素和F3的最后一个元素或更自定义的东西你可以通过研究下面的代码来做到这一点

 var res = (from element in list)
          .GroupBy(x => x.F1)
          .Select(y => new
           {
             F1 = y.FirstOrDefault().F1;
             F2 = y.First().F2;
             F3 = y.Last().F3;
           });
Run Code Online (Sandbox Code Playgroud)

所以你会得到类似的东西

   F1            F2             F3 
 -----------------------------------
   Nima          1990           12
   John          2001           2
   Sara          2010           4
Run Code Online (Sandbox Code Playgroud)

  • 新对象的分隔符或分隔符应该是逗号而不是分号。请检查。 (3认同)