我有一个聊天应用程序和侧边栏。我需要显示所有用户名和我与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结构不是最好的方法还是必须有一个很好的方法来实现结果。请指教。
答案 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);