如何查询用户的会话摘要并显示最新消息

时间:2017-04-03 13:32:09

标签: c# asp.net entity-framework chat

我有一个聊天应用程序和侧边栏。我需要显示所有用户名和我与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在两个属性中(从/到)。可能是Table结构不是最好的方法还是必须有一个很好的方法来实现结果。请指教。

1 个答案:

答案 0 :(得分: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);