如何使我的多对多查询更快?
Posted
技术标签:
【中文标题】如何使我的多对多查询更快?【英文标题】:How can I make my Many-to-Many queries faster? 【发布时间】:2014-02-02 08:38:34 【问题描述】:我的应用程序中的一个页面用于显示公司过去出现的“问题”。这些问题由单个用户提交到数据库,但分配了一个或多个其他用户来处理问题,反之亦然,可以分配单个用户来处理一个或多个问题。
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 秒的等待,这是不可接受的。
【问题讨论】:
【参考方案1】:更改您的 loModel 以加入所有三个表。然后,您将只需要一个foreach
。
【讨论】:
据我了解,使用 LINQ 代码是不可行的。如果您可以提供一个代码 sn-p,那将意味着什么 - 否则,您的答案只是陈述显而易见的。【参考方案2】:试试这样的:
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 到 Problems 到 ProblemUsers(受让人?)再到 Users,所有数据一次可用。您可能希望按对象、按问题或按分配的用户将其组合在一起,具体取决于您尝试生成的显示。
【讨论】:
问题是实体框架没有将 ProblemUser(见上图)视为一个单独的表,而是作为一个关系,所以我无法像访问用户和问题那样访问它.以上是关于如何使我的多对多查询更快?的主要内容,如果未能解决你的问题,请参考以下文章