/// <summary>
        /// 创建 <see cref="PeoplePage"/>
        /// </summary>
        /// <param name="userId">用户 ID</param>
        /// <param name="currentUserId">当前登录用户 ID</param>
        /// <param name="dbContext"><see cref="KeylolDbContext"/></param>
        /// <param name="cachedData"><see cref="CachedDataProvider"/></param>
        /// <returns><see cref="PeoplePage"/></returns>
        public static async Task <PeoplePage> CreateAsync(string userId, string currentUserId, KeylolDbContext dbContext,
                                                          CachedDataProvider cachedData)
        {
            var friends = await UserEntryList.CreateAsync(userId, currentUserId, UserRelationship.Friend, true, 1,
                                                          dbContext, cachedData);

            var subscribedUsers = await UserEntryList.CreateAsync(userId, currentUserId,
                                                                  UserRelationship.SubscribedUser, true, 1, dbContext, cachedData);

            var subscribers = await UserEntryList.CreateAsync(userId, currentUserId, UserRelationship.Subscriber,
                                                              true, 1, dbContext, cachedData);

            return(new PeoplePage
            {
                FriendPageCount = friends.Item2,
                Friends = friends.Item1,
                SubscribedUserPageCount = subscribedUsers.Item2,
                SubscribedUsers = subscribedUsers.Item1,
                SubscriberPageCount = subscribers.Item2,
                Subscribers = subscribers.Item1
            });
        }
        /// <summary>
        /// 创建 <see cref="UserEntryList"/>
        /// </summary>
        /// <param name="userId">用户 ID</param>
        /// <param name="currentUserId">当前登录用户 ID</param>
        /// <param name="relationship">要获取的关系</param>
        /// <param name="returnCount">是否返回总数和总页数</param>
        /// <param name="page">分页页码</param>
        /// <param name="dbContext"><see cref="KeylolDbContext"/></param>
        /// <param name="cachedData"><see cref="CachedDataProvider"/></param>
        /// <returns>Item1 表示 <see cref="UserEntryList"/>,Item2 表示总页数</returns>
        public static async Task <Tuple <UserEntryList, int> > CreateAsync(string userId, string currentUserId,
                                                                           UserRelationship relationship, bool returnCount, int page, KeylolDbContext dbContext,
                                                                           CachedDataProvider cachedData)
        {
            switch (relationship)
            {
            case UserRelationship.Friend:
            {
                var friendIds = await cachedData.Subscriptions.GetFriendsAsync(userId);

                var friendCount = friendIds.Count;
                friendIds.Reverse();
                var skip = RecordsPerPage * (page - 1);
                friendIds = friendIds.Skip(skip).Take(RecordsPerPage).ToList();
                var queryResult = (from id in friendIds
                                   join user in await(from user in dbContext.Users
                                                      where friendIds.Contains(user.Id)
                                                      select new
                    {
                        user.Id,
                        user.IdCode,
                        user.AvatarImage,
                        user.UserName,
                        user.GamerTag,
                        ArticleCount = dbContext.Articles.Count(a => a.AuthorId == user.Id),
                        ActivityCount = dbContext.Activities.Count(a => a.AuthorId == user.Id)
                    }).ToListAsync() on id equals user.Id
                                   select user).ToList();

                var result = new UserEntryList(queryResult.Count);
                foreach (var u in queryResult)
                {
                    result.Add(new UserEntry
                        {
                            Id            = u.Id,
                            IdCode        = u.IdCode,
                            AvatarImage   = u.AvatarImage,
                            UserName      = u.UserName,
                            GamerTag      = u.GamerTag,
                            ArticleCount  = u.ArticleCount,
                            ActivityCount = u.ActivityCount,
                            LikeCount     = await cachedData.Likes.GetUserLikeCountAsync(u.Id),
                            Subscribed    = string.IsNullOrWhiteSpace(currentUserId)
                                ? (bool?)null
                                : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, u.Id,
                                                                                   SubscriptionTargetType.User),
                            IsFriend = string.IsNullOrWhiteSpace(currentUserId)
                                ? (bool?)null
                                : await cachedData.Users.IsFriendAsync(currentUserId, u.Id)
                        });
                }
                return(new Tuple <UserEntryList, int>(result,
                                                      friendCount > 0 ? (int)Math.Ceiling(friendCount / (double)RecordsPerPage) : 1));
            }

            case UserRelationship.SubscribedUser:
            {
                var queryResult = await(from subscription in dbContext.Subscriptions
                                        where subscription.SubscriberId == userId &&
                                        subscription.TargetType == SubscriptionTargetType.User
                                        join user in dbContext.Users on subscription.TargetId equals user.Id
                                        orderby subscription.Sid descending
                                        select new
                    {
                        user.Id,
                        user.IdCode,
                        user.AvatarImage,
                        user.UserName,
                        user.GamerTag,
                        ArticleCount  = dbContext.Articles.Count(a => a.AuthorId == user.Id),
                        ActivityCount = dbContext.Activities.Count(a => a.AuthorId == user.Id)
                    }).TakePage(page, RecordsPerPage).ToListAsync();

                var result = new UserEntryList(queryResult.Count);
                foreach (var u in queryResult)
                {
                    result.Add(new UserEntry
                        {
                            Id            = u.Id,
                            IdCode        = u.IdCode,
                            AvatarImage   = u.AvatarImage,
                            UserName      = u.UserName,
                            GamerTag      = u.GamerTag,
                            ArticleCount  = u.ArticleCount,
                            ActivityCount = u.ActivityCount,
                            LikeCount     = await cachedData.Likes.GetUserLikeCountAsync(u.Id),
                            Subscribed    = string.IsNullOrWhiteSpace(currentUserId)
                                ? (bool?)null
                                : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, u.Id,
                                                                                   SubscriptionTargetType.User),
                            IsFriend = string.IsNullOrWhiteSpace(currentUserId)
                                ? (bool?)null
                                : await cachedData.Users.IsFriendAsync(currentUserId, u.Id)
                        });
                }
                var count = await cachedData.Subscriptions.GetSubscribedUserCountAsync(userId);

                return(new Tuple <UserEntryList, int>(result,
                                                      count > 0 ? (int)Math.Ceiling(count / (double)RecordsPerPage) : 1));
            }

            case UserRelationship.Subscriber:
            {
                var queryResult = await(from subscription in dbContext.Subscriptions
                                        where subscription.TargetId == userId &&
                                        subscription.TargetType == SubscriptionTargetType.User
                                        orderby subscription.Sid descending
                                        select new
                    {
                        subscription.Subscriber.Id,
                        subscription.Subscriber.IdCode,
                        subscription.Subscriber.AvatarImage,
                        subscription.Subscriber.UserName,
                        subscription.Subscriber.GamerTag,
                        ArticleCount  = dbContext.Articles.Count(a => a.AuthorId == subscription.SubscriberId),
                        ActivityCount = dbContext.Activities.Count(a => a.AuthorId == subscription.SubscriberId)
                    }).TakePage(page, RecordsPerPage).ToListAsync();

                var result = new UserEntryList(queryResult.Count);
                foreach (var u in queryResult)
                {
                    result.Add(new UserEntry
                        {
                            Id            = u.Id,
                            IdCode        = u.IdCode,
                            AvatarImage   = u.AvatarImage,
                            UserName      = u.UserName,
                            GamerTag      = u.GamerTag,
                            ArticleCount  = u.ArticleCount,
                            ActivityCount = u.ActivityCount,
                            LikeCount     = await cachedData.Likes.GetUserLikeCountAsync(u.Id),
                            Subscribed    = string.IsNullOrWhiteSpace(currentUserId)
                                ? (bool?)null
                                : await cachedData.Subscriptions.IsSubscribedAsync(currentUserId, u.Id,
                                                                                   SubscriptionTargetType.User),
                            IsFriend = string.IsNullOrWhiteSpace(currentUserId)
                                ? (bool?)null
                                : await cachedData.Users.IsFriendAsync(currentUserId, u.Id)
                        });
                }
                var count =
                    await cachedData.Subscriptions.GetSubscriberCountAsync(userId, SubscriptionTargetType.User);

                return(new Tuple <UserEntryList, int>(result,
                                                      count > 0 ? (int)Math.Ceiling(count / (double)RecordsPerPage) : 1));
            }

            default:
                throw new ArgumentOutOfRangeException(nameof(relationship), relationship, null);
            }
        }
 /// <summary>
 /// 获取用户听众列表
 /// </summary>
 /// <param name="userId">用户 ID</param>
 /// <param name="page">分页页码</param>
 /// <param name="dbContext"><see cref="KeylolDbContext"/></param>
 /// <param name="cachedData"><see cref="CachedDataProvider"/></param>
 /// <returns><see cref="UserEntryList"/></returns>
 public static async Task <UserEntryList> GetSubscribers(string userId, int page,
                                                         [Injected] KeylolDbContext dbContext, [Injected] CachedDataProvider cachedData)
 {
     return((await UserEntryList.CreateAsync(userId, StateTreeHelper.GetCurrentUserId(),
                                             UserRelationship.Subscriber, false, page, dbContext, cachedData)).Item1);
 }