选择所有列,但只能在linq中分组

时间:2016-08-11 10:00:37

标签: c# sql-server entity-framework linq

我一直在寻找一种方法来获取多个列,但在SQL中只有一个列,我找到了一些信息。但是我无法想出一个在linq中做到这一点的方法。

我有以下玩具示例表:

| Id | Message | GroupId | Date |
|-------------------------------|
| 1  | Hello   | 1       | 1:00 |
| 2  | Hello   | 1       | 1:01 |
| 3  | Hey     | 2       | 2:00 |
| 4  | Dude    | 3       | 3:00 |
| 5  | Dude    | 3       | 3:01 |

我想恢复具有不同GroupId的行的所有列,如下所示(使用'日期' desc顺序):

| Id | Message | GroupId | Date |
|-------------------------------|
| 1  | Hello   | 1       | 1:00 |
| 3  | Hey     | 2       | 2:00 |
| 4  | Dude    | 3       | 3:00 |

我并不关心从分组的那一行中挑选哪一行(第一,第二......),只要给出该组ID的唯一一行。

到目前为止,我已经提出了以下代码,但它没有做到应该做的事情:

List<XXX> messages = <MyRep>.Get(<MyWhere>)
                            .GroupBy(x => x.GroupId)
                            .Select(grp => grp.OrderBy(x => x.Date))
                            .OrderBy(y => y.First().Date)
                            .SelectMany(y => y).ToList();

1 个答案:

答案 0 :(得分:12)

这将为每组提供一个项目:

List<dynamic> data = new List<dynamic>
{
    new {ID  = 1, Message = "Hello", GroupId = 1, Date = DateTime.Now},
    new {ID  = 2, Message = "Hello", GroupId = 1, Date = DateTime.Now},
    new {ID  = 3, Message = "Hey",   GroupId = 2, Date = DateTime.Now},
    new {ID  = 4, Message = "Dude",  GroupId = 3, Date = DateTime.Now},
    new {ID  = 5, Message = "Dude",  GroupId = 3, Date = DateTime.Now},
};

var result = data.GroupBy(item => item.GroupId)
                 .Select(grouping => grouping.FirstOrDefault())
                 .OrderByDescending(item => item.Date)
                 .ToList();

//Or you can also do like this:
var result = data.GroupBy(item => item.GroupId)
                 .SelectMany(grouping => grouping.Take(1))
                 .OrderByDescending(item => item.Date)
                 .ToList();

如果您想控制OrderBy,那么:

var result = data.GroupBy(item => item.GroupId)
                 .SelectMany(grouping => grouping.OrderBy(item => item.Date).Take(1))
                 .OrderByDescending(item => item.Date)
                 .ToList();