How can I group one of two possible fields using LINQ?

I am trying to get the last contact with this user, grouped by user:

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

User contact information can be in SentTo or SentFrom .

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

will give me the last message, but I need the last message for each user. The closest solution I could find was LINQ Max Date with a group , but I cannot find the correct syntax. I would prefer not to create multiple List objects if I don't need it. If the user information is in SentTo , my information will be in SentFrom and vice versa, so I have a way to check where the user data is.

Did I mention I was very familiar with LINQ? Any help would be greatly appreciated.

+5
source share
2 answers

Since you need to interpret each entry twice - for example, SentTo and SentFrom , the query becomes a bit complicated:

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

The key trick is in SelectMany , which makes each ChatMessage element into two anonymous elements - one that connects the SentFrom user to SendDate , and one that connects the SentTo user from the same date.

Once you have both entries in an enumerable, the rest is simple: you group the user, and then apply the request from your message to each group.

+3
source

This should be pretty easy, look at this code:

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

It simply filters your collection by selecting items that either SentFrom or SentTo equal username .

0
source

All Articles