【问题标题】:Select all columns but group by only one in linq选择所有列,但在 linq 中仅按一个分组
【发布时间】:2016-08-11 10:00:36
【问题描述】:

我一直在寻找一种方法来获取多个列,但在 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 的行的所有列,如下所示(使用“日期”降序顺序):

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

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 请注意,FirstOrDefault 可以替换为 First,因为保证一个组至少有 1 个项目。
    • @Gilad 看起来我把事情复杂化了......你不仅解决了我的问题,而且还通过这些例子提供了一些理解!谢谢
    • @Tekerson - 不客气 :) 也许还可以查看 SO Documentation for linq - 关于 Take 的精彩部分 SelectMany, OrderBy - 可以从中学到很多东西:)
    • 你能举个VB.Net的例子吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-24
    • 2015-08-03
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 2013-08-22
    相关资源
    最近更新 更多