如何使用 LINQ 对两个可能的字段之一进行分组



我正在尝试获取给定用户的最新联系人,按用户分组:

public class ChatMessage
{
    public string SentTo { get; set; }
    public string SentFrom { get; set; }
    public string MessageBody { get; set; }
    public string SendDate { get; set; }
}

用户的联系信息可以是SentTo,也可以是SentFrom

List<ChatMessage> ecml = new List<ChatMessage>();
var q = ecml.OrderByDescending(m => m.SendDate).First();

会给我最新的消息,但我需要每个用户的最后一条消息。我能找到的最接近的解决方案是带有分组依据的 LINQ Max Date,但我似乎无法找出正确的语法。如果没有必要,我宁愿不创建多个 List 对象。如果用户的信息在SentTo,我的信息将在SentFrom,反之亦然,所以我确实有一些方法可以检查用户的数据在哪里。

我有没有提到我对 LINQ 很陌生?任何帮助将不胜感激。

由于您需要将每条记录解释两次 - 即作为SentToSentFrom,查询变得有点棘手:

var res = ecml
    .SelectMany(m => new[] {
        new { User = m.SentFrom, m.SendDate }
    ,   new { User = m.SentTo, m.SendDate }
    })
    .GroupBy(p => p.User)
    .Select(g => new {
        User = g.Key
    ,   Last = g.OrderByDescending(m => m.SendDate).First()
    });

关键技巧是在 SelectMany 中,它使每个ChatMessage项目变成两个匿名项目 - 一个将SentFrom用户与SendDate配对,另一个将SentTo用户与同一日期配对。

在可枚举项中同时拥有两条记录后,其余的就很简单了:按用户分组,然后将帖子中的查询应用于每个组。

这应该很容易,看看这段代码:

string username = "John";
var q = ecml.Where(i=>i.SentFrom == username || i.SentTo == username).OrderByDescending(m => m.SendDate).First();

它只是过滤您的集合,选择"发送源"或"发送至"等于username的项目。

最新更新