如何更快地进行多对多查询?

时间:2014-01-14 10:18:25

标签: c# sql-server asp.net-mvc linq

我的应用程序中的页面用于显示过去出现的公司“问题”。这些问题由单个用户提交给数据库,但是分配了一个或多个其他用户来处理问题,反之亦然,可以指派单个用户来处理一个或多个问题。

This是这种关系的样子。 我遇到的主要问题是,在发出getAllProblems()请求时,我必须检查分配给问题的所有用户,这会让我在foreach内遇到一个丑陋的foreach。我的代码如下所示:

public HttpResponseMessage GetProblems(String ClientUserHash) {
         this.ClientUserHash = ClientUserHash;

          HttpResponseMessage loResponse;

          if (!CheckClientHash()) {
              SetResponseToBad(out loResponse);
          } else {
              List<Int64> loFilteredObjects = PermissionsHelper.UserObjects(ClientUserID);
              var loModel = (from p in MeridianDatabase.Problems                                 
                             join o in MeridianDatabase.Objects on p.ObjectID equals o.ObjectID
                             where loFilteredObjects.Contains(o.ObjectID) && ((p.Archive == false) || (p.Archive == null))
                             select new ProblemsModel {
                                 ProblemID =     p.ProblemID,
                                 Description =   p.Description,
                                 Comment =       p.Comment,
                                 Status =        p.Status,
                                 Picture =       p.Picture,
                                 DateOpen =      p.DateOpen,
                                 DateClosed =    p.DateClosed,
                                 CategoryID =    p.CategoryID,
                                 CategoryName =  p.ProblemCategory.Name,
                                 ObjectID =      p.ObjectID,
                                 ObjectName =    p.Object.Name,
                                 EmployeeID =    p.EmployeeID,
                                 FullName =      p.Employee.Candidate.FirstName + " " + p.Employee.Candidate.LastName,
                                 CompanyName =   p.Object.Company.Name
                             }).ToList();
              foreach (ProblemsModel toProblem in loModel) {
                  var toDbUsers = MeridianDatabase.Problems.Where(x => x.ProblemID == toProblem.ProblemID).FirstOrDefault().Users;
                  if (toDbUsers.Count > 0) {
                      toProblem.ProblemUsers = new List<string>();
                      List<UsersModel> toUsersList = new List<UsersModel>();
                      foreach (User toUser in toDbUsers) {
                          toProblem.ProblemUsers.Add(String.Format("{0}-{1}", toUser.UserID, toUser.Username));
                          UsersModel toUserModel = new UsersModel() {
                              UserID = toUser.UserID,
                              Username = toUser.Username,
                              Password = toUser.Password,
                              Email = toUser.Email,
                              UserGroupsID = toUser.PermissionLevelID,
                              IsAdmin = toUser.IsAdmin,
                              LanguageID = toUser.LanguageID,
                              Name = toUser.Nickname
                          };
                          toUsersList.Add(toUserModel);
                      }
                      toProblem.Users = toUsersList;
                  }
              }
              loResponse = Request.CreateResponse(HttpStatusCode.OK, loModel);
          }
        return loResponse;
    }

我尝试使用代码内秒表并推断foreach是罪魁祸首。如果不依靠编写存储过程,我可以获得更好的性能吗?现在的方式,获取400行导致等待6-9秒,这是不可接受的。

2 个答案:

答案 0 :(得分:0)

更改您的loModel以加入所有三个表。然后,您只需要一个foreach

答案 1 :(得分:0)

尝试这样的事情:

from client_uo in UserObjects
join client_obj in Objects on client_uo.ObjectID == client_obj.ObjectID
join p in Problems on p.ObjectID == clt_obj.ObjectID
join pu in ProblemUsers on p.ProblemID == pu.ProblemID
join assignee in Users on pu.UserID == assignee.UserID
where client_obj.UserID == ClientUserID

应该产生一个多连接,它可以让你从ClientUserID到Client-UserObjects到ProblemObjects,再到ProblemUsers(受让人?)到用户的问题,一次性获得所有数据。您可能希望按对象,按问题或由指定的用户将它们组合在一起,具体取决于您尝试生成的显示。