Comment puis-je rendre mes requêtes Many-to-Many plus rapides?

Une page de mon application sert à afficher les «problèmes» de l'entreprise qui sont survenus dans le passé. Ces problèmes sont soumis à la database par un seul user, mais un ou plusieurs autres users sont assignés pour traiter le problème, et vice-versa, un seul user peut être assigné pour traiter un ou plusieurs problèmes.

C'est à quoi ressemble la relation. Mon problème principal avec ceci est que lors de l'émission d'une getAllProblems() , je dois passer par tous les users affectés à des problèmes, ce qui m'amène à une foreach moche dans un foreach . Mon code ressemble à ceci:

 public HttpResponseMessage GetProblems(Ssortingng 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<ssortingng>(); List<UsersModel> toUsersList = new List<UsersModel>(); foreach (User toUser in toDbUsers) { toProblem.ProblemUsers.Add(Ssortingng.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; } 

J'ai essayé d'utiliser le chronomètre dans le code et inféré que le foreach est le coupable. Puis-je get de meilleures performances sans recourir à l'écriture de procédures stockées? La façon dont les choses sont maintenant, en récupérant 400 lignes, donne une attente de 6-9 secondes, ce qui est inacceptable.

Changez votre loModel pour join les trois tables. Ensuite, vous aurez besoin d'un foreach seulement.

Essayez quelque chose comme ceci:

 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 

Cela devrait produire une jointure multiple qui vous amène de ClientUserID à Client-UserObjects à ProblemObjects à Problems to ProblemUsers (cessionnaires?) aux users, avec toutes datatables disponibles en une seule fois. Vous pouvez le regrouper, soit par object, par problème ou par user assigné, en fonction de l'affichage que vous essayez de produire.