diff --git a/aspnet-core/modules/realtime-message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreMessageRepository.cs b/aspnet-core/modules/realtime-message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreMessageRepository.cs index 0433a0a47..6349998a4 100644 --- a/aspnet-core/modules/realtime-message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreMessageRepository.cs +++ b/aspnet-core/modules/realtime-message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Chat/EfCoreMessageRepository.cs @@ -1,4 +1,4 @@ -using LINGYUN.Abp.IM.Messages; +using LINGYUN.Abp.IM.Messages; using LINGYUN.Abp.MessageService.EntityFrameworkCore; using LINGYUN.Abp.MessageService.Groups; using Microsoft.EntityFrameworkCore; @@ -170,274 +170,75 @@ public class EfCoreMessageRepository : EfCoreRepository(); - //using var reader = await command.ExecuteReaderAsync(); - - //T GetValue(DbDataReader reader, int index) - //{ - // var value = reader.GetValue(index); - // if (value == null || value == DBNull.Value) - // { - // return default; - // } - - // var valueType = typeof(T); - // var converter = TypeDescriptor.GetConverter(valueType); - // if (converter.CanConvertFrom(value.GetType())) - // { - // return (T)converter.ConvertFrom(value); - // } - // return (T)Convert.ChangeType(value, typeof(T)); - //}; - - //ExtraPropertyDictionary GetExtraProperties(DbDataReader reader, int index) - //{ - // var value = reader.GetValue(index); - // if (value == null || value == DBNull.Value) - // { - // return new ExtraPropertyDictionary(); - // } - // var extraPropertiesAsJson = value.ToString(); - // if (extraPropertiesAsJson.IsNullOrEmpty() || extraPropertiesAsJson == "{}") - // { - // return new ExtraPropertyDictionary(); - // } - - // var deserializeOptions = new JsonSerializerOptions(); - // deserializeOptions.Converters.Add(new ObjectToInferredTypesConverter()); - - // var dictionary = JsonSerializer.Deserialize(extraPropertiesAsJson, deserializeOptions) ?? - // new ExtraPropertyDictionary(); - - // return dictionary; - //} - - //while (reader.Read()) - //{ - // messages.Add(new LastChatMessage - // { - // Content = GetValue(reader, 0), - // SendTime = GetValue(reader, 1), - // FormUserId = GetValue(reader, 2), - // FormUserName = GetValue(reader, 3), - // Object = GetValue(reader, 4), - // AvatarUrl = GetValue(reader, 5), - // Source = (MessageSourceType)GetValue(reader, 6), - // MessageId = GetValue(reader, 7), - // MessageType = (MessageType)GetValue(reader, 8), - // TenantId = GetValue(reader, 9), - // ToUserId = GetValue(reader, 10), - // GroupId = GetValue(reader, 11), - // ExtraProperties = GetExtraProperties(reader, 12), - // }); - //} - - //return messages; - #endregion - - #region 待 EF 团队解决此问题 - - //// 聚合用户消息 - var aggreUserMsgIdQuery = dbContext.Set() - .Where(msg => msg.ReceiveUserId == userId) - .WhereIf(state.HasValue, x => x.State == state) - .GroupBy(msg => msg.ReceiveUserId) - .Select(msg => new + var token = GetCancellationToken(cancellationToken); + + // 使用Union All合并用户消息和群组消息查询 + var lastMessages = await ( + // 用户消息查询 + from um in dbContext.Set() + join ucc in dbContext.Set() + on um.CreatorId equals ucc.UserId + where um.ReceiveUserId == userId && + (state == null || um.State == state) && + um.MessageId == ( + from subUm in dbContext.Set() + where subUm.ReceiveUserId == userId && + subUm.CreatorId == um.CreatorId + select subUm.MessageId + ).Max() + select new LastChatMessage { - MessageId = msg.Max(x => x.MessageId) - }); - var joinUserMsg = from um in dbContext.Set() - join aum in aggreUserMsgIdQuery - on um.MessageId equals aum.MessageId - join ucc in dbContext.Set() - on um.CreatorId equals ucc.UserId - select new LastChatMessage - { - Content = Convert.ToString(um.Content), - SendTime = um.CreationTime, - FormUserId = um.CreatorId.Value, - FormUserName = Convert.ToString(um.SendUserName), - Object = Convert.ToString(ucc.NickName), - AvatarUrl = Convert.ToString(ucc.AvatarUrl), - Source = um.Source, - MessageId = Convert.ToString(um.MessageId), - MessageType = um.Type, - TenantId = um.TenantId, - ToUserId = Convert.ToString(um.ReceiveUserId), - GroupId = Convert.ToString(""), - }; - // 聚合群组消息 - var aggreGroupMsgIdQuery = from ucc in dbContext.Set() - join ucg in dbContext.Set() - on ucc.UserId equals ucg.UserId - join gm in dbContext.Set() - on ucg.GroupId equals gm.GroupId - where ucc.UserId.Equals(userId) - group gm by gm.GroupId into ggm - select new - { - MessageId = ggm.Max(gm => gm.MessageId), - }; - - var joinGroupMsg = from gm in dbContext.Set() - join agm in aggreGroupMsgIdQuery - on gm.MessageId equals agm.MessageId - join cg in dbContext.Set() - on gm.GroupId equals cg.GroupId - select new LastChatMessage - { - Content = Convert.ToString(gm.Content), - SendTime = gm.CreationTime, - FormUserId = gm.CreatorId.Value, - FormUserName = Convert.ToString(gm.SendUserName), - Object = Convert.ToString(cg.Name), - AvatarUrl = Convert.ToString(cg.AvatarUrl), - Source = gm.Source, - MessageId = Convert.ToString(gm.MessageId), - MessageType = gm.Type, - TenantId = gm.TenantId, - ToUserId = Convert.ToString(""), - GroupId = Convert.ToString(gm.GroupId) - }; - - return await joinUserMsg - .Concat(joinGroupMsg) + Content = um.Content, + SendTime = um.CreationTime, + FormUserId = um.CreatorId.Value, + FormUserName = um.SendUserName, + Object = ucc.NickName, + AvatarUrl = ucc.AvatarUrl, + Source = um.Source, + MessageId = um.MessageId.ToString(), + MessageType = um.Type, + TenantId = um.TenantId, + ToUserId = um.ReceiveUserId.ToString(), + GroupId = "" + }) + .Union( + // 群组消息查询 + from gm in dbContext.Set() + join cg in dbContext.Set() + on gm.GroupId equals cg.GroupId + join ucg in dbContext.Set() + on new { GroupId = gm.GroupId, UserId = userId } equals new { ucg.GroupId, ucg.UserId } + where (state == null || gm.State == state) && + gm.MessageId == ( + from subGm in dbContext.Set() + where subGm.GroupId == gm.GroupId + select subGm.MessageId + ).Max() + select new LastChatMessage + { + Content = gm.Content, + SendTime = gm.CreationTime, + FormUserId = gm.CreatorId.Value, + FormUserName = gm.SendUserName, + Object = cg.Name, + AvatarUrl = cg.AvatarUrl, + Source = gm.Source, + MessageId = gm.MessageId.ToString(), + MessageType = gm.Type, + TenantId = gm.TenantId, + ToUserId = "", + GroupId = gm.GroupId.ToString() + } + ) + // 排序和分页 .OrderBy(sorting) .Take(maxResultCount) - .ToListAsync(GetCancellationToken(cancellationToken)); - - #endregion + .ToListAsync(token); + return lastMessages; } public async virtual Task> GetUserMessagesAsync(