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

时间:2015-04-16 14:14:08

标签: c# linq group-by

我正在尝试与给定用户进行最新联系,按用户分组:

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

用户的联系信息可以位于SentToSentFrom

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

会给我最新的消息,但我需要每个用户的最后一条消息。 我能找到的最接近的解决方案是LINQ Max Date with group by,但我似乎无法弄清楚正确的语法。如果我不需要,我宁愿不创建多个List对象。 如果用户的信息位于SentTo,我的信息将显示在SentFrom中,反之亦然,因此我确实可以通过某种方式检查用户数据的位置。

我提到过我对LINQ很新吗?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:3)

由于您需要对每条记录进行两次解释 - 例如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用户。

一旦你有两个可记录的记录,剩下的就很简单了:你按用户分组,然后将你的帖子中的查询应用到每个组。

答案 1 :(得分:0)

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

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

只需过滤您的收藏集即可选择SentFrom或SentTo等于username的项目。