2010-10-28 92 views
2

我有一个客户名单,我需要根据业务规则对列表进行排序和分组。linq分组和排序

  • 组由客户名称
  • 排序按字母顺序
  • 如果有相同名称的几个结果,那么就需要通过出生日期进行升序排序(最老的上市客户名称第一个)

下面是实体。

public class Customer 
{ 
public string FirstName {get; set;} 
public string LastName {get; set;} 
public DateTime DateofBirth {get; set;} 
} 

在此先感谢。

customers.GroupBy(c => c.FirstName) 
.Select(c => c.OrderBy(c => c.FirstName).ThenBy(c => c.LastName)); 

回答

2

你的业务规则是有点矛盾的: Group by Customer Name意味着你不会有相同的名字多次出现在结果列表中。然而你的第三条规则是if there are several results for the same name, then they need to sorted by date of birth。所以,如果在规则#1分组你的意思是排序,您的查询将仅仅是:

customers.OrderBy(c => c.FirstName). 
      ThenBy(c => c.LastName). 
      ThenBy(c => c.DateofBirth); 

如果你真正的意思是分组规则#3成为标准组中选择元素 - 在这种情况下,最早的客户将选择对于每个组:

customers.GroupBy(c => c.FirstName + c.LastName). 
      Select(g => g.OrderBy(c => c.DateofBirth).FirstOrDefault()). 
      OrderBy(c => c.FirstName). 
      ThenBy(c => c.LastName); 
+0

第三个规则是情况下,如果列表中有更多的一个客户有相同的名称。那时按DateofBirth排序。 – 2010-10-28 11:56:41

+0

正如我前面提到的 - 如果您有多个同名客户,他们将被分组为一个。但是如果你不想'合并'它们,你并不需要'GroupBy' - 只需使用'OrderBy(...)。ThenBy(...)。ThenBy(...)'。你期望什么样的输出,顺便说一句?如果你想要一个简单的列表 - 在我的查询中使用'ToList()',如果你想要,例如'List >' - 应用'ToList()'给Mark Heath的答案。 – Yakimych 2010-10-28 12:46:23

0
var sortList = (from c in customers 
          group c by new 
          { 
           c.FirstName, 
           c.LastName, 
           c.DateofBirth 
          } into g 
          select new Customer() 
          { 
           FirstName = g.Key.FirstName, 
           LastName = g.Key.LastName, 
           DateofBirth = g.Key.DateofBirth 
          }).OrderBy(x => x.FirstName) 
          .ThenBy(x=> x.LastName) 
          .ThenBy(x=> x.DateofBirth); 
2

这似乎有点奇怪,以客户的名义组,但是这将做到这

var groups = from c in customers 
       let name = c.FirstName + " " + c.LastName 
       orderby name ascending, c.DateofBirth ascending 
       group c by name into g 
       select g; 
+0

你真的不需要名称之间的空间,是吗? – Yakimych 2010-10-28 10:56:27

+0

@Yakimych以及它使组。键看起来更好一点 – 2010-10-28 11:01:26