2017-04-03 64 views
0

我有一個聊天應用程序,並在側邊欄。我需要使用Entity Framework顯示所有用戶的姓名以及與他們對話的最後一條消息。以下是實體對象如何查詢與用戶對話摘要並顯示最新消息

public partial class ObjectMessage 
{ 
    public int Id { get; set; } 
    public int FromUserId { get; set; } 
    public int ToUserId { get; set; } 
    public string Body { get; set; } 
    public System.DateTime DateSent { get; set; } 
    public bool Unread { get; set; } 

} 

我嘗試了以下查詢,但沒有產生所需的結果。

  var messages = db.ObjectMessages.Where(x => x.ToUserId == userId || x.FromUserId == userId) 
      .OrderByDescending(x => x.DateSent) 
      .GroupBy(x => new { x.ToUserId, x.FromUserId }) 
      .Select(x => new LastMessage 
      { 
       FromUserId = x.FirstOrDefault().FromUserId, 
       ToUserId = x.FirstOrDefault().ToUserId, 
       Body = x.FirstOrDefault().Body, 
       DateSent = x.FirstOrDefault().DateSent, 
       Me = x.FirstOrDefault().FromUserId == userId, 
       Unread = x.Count(i=> i.Unread) 
      }).OrderBy(x=> x.DateSent).ToList(); 

我的用戶ID在兩個屬性(From/To)中。可能是表結構不是最好的方法,或者必須有一個很好的方法來實現結果。請指教。

+0

順便說一句,我有一個單獨的用戶列表,我將追加每個最後的消息到其相關的用戶。 – Khalil

+0

當你是'FromUserId',然後'ToUserId'並且將它們合併成'Dictionary '這樣的東西時,你需要最後一條消息。 –

+0

無論我是FromUserId還是ToUserId,都需要最新的消息。這樣做的目的是,我把所有的朋友列表名稱放在每個名字下面,以顯示來自對話的最後一條消息,無論它來自我還是他。 – Khalil

回答

1

假設有以下試驗數據:

var messages = new List<ObjectMessage>(); 
messages.Add(new ObjectMessage { Id = 1000, Body = "AAA", DateSent = new DateTime(2017, 01, 14, 0, 0, 0), Unread = false, FromUserId = 1, ToUserId = 6 }); 
messages.Add(new ObjectMessage { Id = 1001, Body = "BBB", DateSent = new DateTime(2017, 01, 14, 0, 0, 0), Unread = false, FromUserId = 3, ToUserId = 2 }); 
messages.Add(new ObjectMessage { Id = 1002, Body = "CCC", DateSent = new DateTime(2017, 01, 14, 0, 0, 0), Unread = false, FromUserId = 7, ToUserId = 6 }); 
messages.Add(new ObjectMessage { Id = 1003, Body = "DDD", DateSent = new DateTime(2017, 01, 15, 0, 0, 0), Unread = false, FromUserId = 1, ToUserId = 6 }); 
messages.Add(new ObjectMessage { Id = 1004, Body = "EEE", DateSent = new DateTime(2017, 02, 18, 0, 0, 0), Unread = false, FromUserId = 2, ToUserId = 3 }); 
messages.Add(new ObjectMessage { Id = 1005, Body = "FFF", DateSent = new DateTime(2017, 01, 14, 0, 0, 0), Unread = false, FromUserId = 1, ToUserId = 7 }); 
messages.Add(new ObjectMessage { Id = 1006, Body = "GGG", DateSent = new DateTime(2017, 02, 20, 0, 0, 0), Unread = false, FromUserId = 8, ToUserId = 9 }); 
messages.Add(new ObjectMessage { Id = 1007, Body = "HHH", DateSent = new DateTime(2017, 03, 11, 0, 0, 0), Unread = false, FromUserId = 9, ToUserId = 8 }); 
messages.Add(new ObjectMessage { Id = 1008, Body = "III", DateSent = new DateTime(2017, 03, 12, 0, 0, 0), Unread = false, FromUserId = 8, ToUserId = 1 }); 
messages.Add(new ObjectMessage { Id = 1009, Body = "JJJ", DateSent = new DateTime(2017, 03, 13, 0, 0, 0), Unread = false, FromUserId = 7, ToUserId = 8 }); 

第一組數據與您發件人:

var messagesAsSender = messages 
    .Where(p => p.FromUserId == 8) 
    .GroupBy(p => new { Me = p.FromUserId, Him = p.ToUserId }) 
    .ToDictionary(
     p => p.Key, 
     p => p.OrderByDescending(t => t.DateSent) 
       .FirstOrDefault()); 

其次組的數據與您接收機:

var messagesAsReceiver = messages 
    .Where(p => p.ToUserId == 8) 
    .GroupBy(p => new { Me = p.ToUserId, Him = p.FromUserId }) 
    .ToDictionary(
     p => p.Key, 
     p => p.OrderByDescending(t => t.DateSent) 
       .FirstOrDefault()); 

最後比較一下,得到最後一條消息:

var messagesLast = messagesAsSender 
    .Concat(messagesAsReceiver) 
    .GroupBy(p => p.Key) 
    .ToDictionary(
     p => p.Key, 
     p => p.OrderByDescending(date => date.Value.DateSent) 
       .FirstOrDefault() 
       .Value 
       .Body); 
+0

謝謝Cristian Szpisjak。它看起來很酷。我會測試它並將此問題標記爲已回答。 – Khalil