You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LINQ to Entities查询当前登录用户的好友及对应私聊Chat ID

解决方法

你当前代码的问题是:Select(x => x.Friend) 仅返回了好友实体,好友关联的 ChatUsers 包含了该好友所有的会话,无法直接筛选出仅属于你和该好友的私聊。

方案1:直接投影查询(适合数据量较小的场景)

首先定义一个数据传输对象(DTO)用来封装返回结果,避免暴露多余的实体字段:

public class FriendWithChatDto
{
    // 可按需扩展好友的其他字段,比如昵称、头像等
    public string FriendId { get; set; }
    public string FriendUserName { get; set; }
    // 你和该好友的私聊ID
    public int? PrivateChatId { get; set; }
}

查询逻辑如下,EF Core 会自动加载投影所需的关联数据,无需手动写 Include:

var result = await _context.Friendships
    .Where(x => x.Status == StatusCode.Accepted && x.ApplicationUserId == userId)
    .Select(x => new FriendWithChatDto
    {
        FriendId = x.Friend.Id,
        FriendUserName = x.Friend.UserName,
        // 筛选同时包含当前登录用户、且是私聊类型的会话
        PrivateChatId = x.Friend.ChatUsers
            .Where(cu => cu.Chat.Type == ChatType.Private 
                      && cu.Chat.ChatUsers.Any(u => u.UserId == userId))
            .Select(cu => cu.Chat.Id)
            .FirstOrDefault()
    })
    .ToListAsync();

方案2:分两次查询(适合好友量较大的场景,性能更优)

如果好友数量较多,嵌套子查询生成的SQL性能较差,可以先把当前用户的所有私聊会话查出来做映射,再和好友列表匹配:

// 第一步:查询当前用户所有私聊,生成「好友ID-私聊ID」的字典
var privateChatMap = await _context.Chats
    .Where(c => c.Type == ChatType.Private && c.ChatUsers.Any(u => u.UserId == userId))
    .Select(c => new 
    {
        ChatId = c.Id,
        // 私聊仅有两个用户,排除自己剩下的就是好友ID
        FriendId = c.ChatUsers.First(u => u.UserId != userId).UserId
    })
    .ToDictionaryAsync(x => x.FriendId, x => x.ChatId);

// 第二步:查询已通过的好友列表
var friends = await _context.Friendships
    .Where(x => x.Status == StatusCode.Accepted && x.ApplicationUserId == userId)
    .Select(x => x.Friend)
    .ToListAsync();

// 第三步:匹配每个好友对应的私聊ID,可自行组装返回格式
foreach (var friend in friends)
{
    if (privateChatMap.TryGetValue(friend.Id, out var chatId))
    {
        // 按需处理ChatId赋值即可
    }
}

内容的提问来源于stack exchange,提问作者JAmes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 03:06:04