1

我有 2 个表:用户和用户朋友

用户用户 ID、Guid

UserFriends ActiveID, Guid - PassiveID, Guid

所以你可以在我的好友列表中,但我不需要在你的好友列表中。对于所有用户的在线列表,首先我获取所有用户并使用 foreach 迭代他们来做我必须在这里做的事情。

List<DAL.User> onlineList = DAL.UserDAL.GetAllOnlineUser();
foreach (DAL.User onlineUser in onlineList)
{
   //do things here
    if (DAL.UserDAL.CheckForFriends(myUserID, onlineUser.UserID))
    {
           //Do things here
    }
}

服务器代码:

 public static List<User> GetAllOnlineUser()
    {
        using (RPGDataContext dc = new RPGDataContext())
        {
            return (from a in dc.Users where a.RefreshPing > DateTime.Now.AddMinutes(-30) orderby a.Username select a).ToList();
        }
    }

public static bool CheckForFriends(Guid userActive, Guid userPassive)
    {
        using (RPGDataContext dc = new RPGDataContext())
        {
            UserFriend uf = (from a in dc.UserFriends where a.UserIDActive == userActive && a.UserIDPassive == userPassive select a).SingleOrDefault();
            return (uf != null);
        }
    }

在这个 foreach 中,我必须检查朋友,如果,我会在在线列表中加入一个朋友符号。这意味着有 20 个在线用户没有我,我必须访问数据库 20 次并返回。如何避免这种情况?

4

4 回答 4

3

正在使用关系数据库(例如 Oracle、MySql、MsSql 等)?

如果是这样,让数据库做它最擅长的事情:编写一个查询,从数据库返回适当的结果。

更新 1

例如,一个 MS SQL 查询可能类似于:

SELECT u.userId, u.refreshPing
FROM userFriends f
JOIN [user] u ON u.userId = f.userFriendId
WHERE DATEDIFF(MINUTE, u.refreshPing, GetDate()) < 6000
AND f.userId = 1

为了时间,我的查询假设:

  • 键是整数(不是 GUID)
  • 用户表 = userId (int), refreshPing (DateTime)
  • userFriends = userId (int), userFriendId (int)
  • 在我的示例中 userFriends.userFriendId 是返回用户表的外键
  • 此查询尚未经过测试

您必须修改查询以匹配您的架构...我不知道您如何管理朋友关系。

更新 2 你可以:

  1. 使用实体框架编写类似的查询(我认为这是您正在使用的技术)
  2. 在数据库上创建一个视图并查询结果
  3. 创建一个存储过程并从您的代码中调用它

我倾向于选项#1。

更新 3

下载 LINQPad www.linqpad.net/‎</p>

于 2013-09-23T13:48:58.487 回答
2

所以你想返回一个在线用户列表并为 IsFriendOfCurrentUser 添加属性?如果您想在单个查询中执行此操作,则不能在 UI 层中使用 DAL 实体。

为您的 UI 创建单独的类,然后如果当前用户是该用户的朋友,则选择具有在线用户详细信息 + 布尔信息的匿名类。并从列表中排除当前用户,因为您可能不想向用户显示他在线。

public static List<InsertClassNameHere> GetAllOnlineUser(Guid userActive)
{
    using (RPGDataContext dc = new RPGDataContext())
    {
        var userList = from u in dc.Users
        join uf in dc.UserFriends on u.UserId equals uf.UserIDPassive into JoinedFriends 
        from uf in JoinedFriends.DefaultIfEmpty()
        where u.UserId != userActive
        select new 
        {
            UserId = u.UserId,
            IsFriend = uf != null ? true : false
        };

        var returnList = new list<InsertClassNameHere>();
        foreach(var user in userList)
        {
            returnList.Add(new InsertClassNameHere()
            {
                UserId = UserId,
                IsFriend = IsFriend 
            };
        }

        return returnList;
    }
}
于 2013-09-23T14:23:22.483 回答
2

在输入之前创建一个查询以返回您的所有朋友,foreach然后只需对照该集合检查每个在线用户

于 2013-09-23T13:40:37.410 回答
0

就像是

var friends = onlineList.Where(a => a.UserIDActive == myUserID && a.UserIDPassive == userPassive);

或者我不明白这个问题。

于 2013-09-23T13:58:56.100 回答