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

优化社交APP「可能认识的人」模块:获取非好友的更优方案?

优化「可能认识的人」查询代码

我正在开发一款类似Facebook的社交APP,支持添加好友功能,想做一个「可能认识的人」板块,展示除好友外的所有应用用户。

现有模型定义

ApplicationUser 模型

public class ApplicationUser : IdentityUser
{
    public string Fullname { get; set; }

    public DateOnly BirthDate { get; set; }

    public string? ProfilePicUrl { get; set; }
    public string Bio {  get; set; }

    public ICollection<User_Friend> Users { get; set; }
    public ICollection<User_Friend> Friends { get; set; }
}

User_Friend 关联模型

public class User_Friend
{
    public int Id { get; set; }

    public string UserId { get; set; }
    public ApplicationUser User { get; set; }

    public string FriendId { get; set; }
    public ApplicationUser Friend { get; set; }

    public DateTime FriendsSince { get; set; }
}

当前实现(功能正常但冗余)

public IActionResult Index()
{
    var claim = (ClaimsIdentity)User.Identity;
    var user = claim.FindFirst(ClaimTypes.NameIdentifier);

    //everyone ids except me
    List<string> AllIds  = _context.applicationUsers
                                   .Where(u => u.Id != user.Value)
                                   .Select(x => x.Id).ToList();

    // friends ids
    List<string> friendsIds = _context.user_Friends 
                                      .Where(u => u.UserId == user.Value)
                                      .Select(x => x.FriendId)
                                      .ToList();

    // non-friends ids
    List<string> nonFriendsIds = AllIds.Except(friendsIds).ToList();

    List<ApplicationUser> nonFriends = new List<ApplicationUser>();
    
    if (user != null)
    {
        foreach (var x in nonFriendsIds)
        {
            nonFriends.Add(_context.applicationUsers.FirstOrDefault(u => u.Id == x));
        }
    }

    return View(nonFriends);
}

优化方案

方案一:单查询直接过滤

通过合并查询逻辑,减少数据库交互次数,同时简化代码:

public IActionResult Index()
{
    var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
    if (userId == null)
    {
        return View(new List<ApplicationUser>());
    }

    var nonFriends = _context.applicationUsers
        .Where(u => u.Id != userId)
        .Where(u => !_context.user_Friends.Any(uf => uf.UserId == userId && uf.FriendId == u.Id))
        .ToList();

    return View(nonFriends);
}

方案二:左连接实现

使用Linq左连接语法,逻辑更直观:

public IActionResult Index()
{
    var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
    if (userId == null)
    {
        return View(new List<ApplicationUser>());
    }

    var nonFriendsQuery = from user in _context.applicationUsers
                          join friendLink in _context.user_Friends
                              on user.Id equals friendLink.FriendId into linkedFriends
                          from link in linkedFriends.DefaultIfEmpty()
                          where user.Id != userId && link == null
                          select user;

    return View(nonFriendsQuery.ToList());
}

优化点总结

  • 用User.FindFirstValue简化当前用户ID的获取,无需强制类型转换
  • 将多次数据库查询合并为一次,降低IO开销
  • 避免先查ID再循环查询用户的冗余操作,直接返回目标用户集合
  • 提前处理未登录场景,返回空列表保证代码健壮性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 20:33:11