2013-07-30 1 views
0

DataTables를 사용하는 프로젝트가 있습니다. Ajax 요청으로 작동합니다. 8-12 초 만에 완료되었습니다. 이 코드를 최적화해야하지만 어떻게해야할지 모르겠다. 문자열 프로세스가 최악입니다.DataTables Asp.Net MVC 4 프로세스

public JsonResult PageModel(Models.DataTable.ParamModel model, byte type) 
    { 
     DateTime startTime = DateTime.Now; 
     using (var db = Helper.Context()) 
     { 
      var allEntries = db.MembershipVacations.Where(i => i.Type == type).ToList(); 
      IEnumerable<DatabaseProcedure.Models.MembershipVacation> list = new List<DatabaseProcedure.Models.MembershipVacation>(); 

      Func<DbModels.MembershipVacation, string> orderingFunction = (c => 
                model.iSortCol_0 == 0 ? c.Membership.Username : ""); 

      Func<DbModels.MembershipVacation, DateTime> dateOrderingFunction = (c => 
                model.iSortCol_0 == 1 ? c.PostDate : 
                model.iSortCol_0 == 3 ? c.StartDate : 
                model.iSortCol_0 == 4 ? c.EndDate : DateTime.MaxValue); 

      /*Func<DbModels.MembershipVacation, string> orderingFunction = (c => model.iSortCol_0 == 1 ? c.ID.ToString() : 
                model.iSortCol_0 == 2 ? c.Membership.Username : 
                c.Description);*/ 

      if (User.IsInRole("Admin")) 
      { 
       if (model.sSearch.IsNull()) 
       { 
        if (model.sSortDir_0 == "asc") 
        { 
         list = allEntries 
          .OrderBy(orderingFunction); 

         if (model.iSortCol_0 == 1 || model.iSortCol_0 == 3 || model.iSortCol_0 == 4) 
         { 
          list = allEntries.OrderBy(dateOrderingFunction); 
         } 
        } 
        else 
        { 
         list = allEntries 
          .OrderByDescending(orderingFunction); 


         if (model.iSortCol_0 == 1 || model.iSortCol_0 == 3 || model.iSortCol_0 == 4) 
         { 
          list = allEntries.OrderByDescending(dateOrderingFunction); 
         } 
        } 
        list = list 
         .Skip(model.iDisplayStart) 
         .Take(model.iDisplayLength); 
       } 
       else 
       { 
        list = allEntries 
         .Where(i => 
         i.Membership != null ? i.Membership.Username.Contains(model.sSearch, StringComparison.OrdinalIgnoreCase) : false 
         || i.Membership != null && i.Membership.Department != null ? i.Membership.Department.Name.Contains(model.sSearch, StringComparison.OrdinalIgnoreCase) : false 
         || i.StartDate.ToString().Contains(model.sSearch, StringComparison.OrdinalIgnoreCase) 
         || i.EndDate.ToString().Contains(model.sSearch, StringComparison.OrdinalIgnoreCase)); 

        if (model.sSortDir_0 == "asc") 
        { 
         list = list 
          .OrderBy(orderingFunction); 

         if (model.iSortCol_0 == 1 || model.iSortCol_0 == 3 || model.iSortCol_0 == 4) 
         { 
          list = list.OrderBy(dateOrderingFunction); 
         } 

        } 
        else 
        { 
         list = list 
          .OrderByDescending(orderingFunction); 

         if (model.iSortCol_0 == 1 || model.iSortCol_0 == 3 || model.iSortCol_0 == 4) 
         { 
          list = list.OrderByDescending(dateOrderingFunction); 
         } 

        } 
       } 
      } 
      else 
      { 
       var approveList = db.MembershipVacationApproves.ToList(); 
       if (model.sSearch.IsNull()) 
       { 
        list = approveList 
         .Where(i => i.MembershipID == UI.Helper.User.ID || i.MembershipVacation.MembershipID == UI.Helper.User.ID) 
         .Select(i => i.MembershipVacation) 
         .Distinct() 
         .Where(i => i.Type == type) 
         .Skip(model.iDisplayStart) 
         .Take(model.iDisplayLength); 
       } 
       else 
       { 
        list = approveList 
         .Where(i => i.MembershipID == UI.Helper.User.ID || i.MembershipVacation.MembershipID == UI.Helper.User.ID) 
         .Select(i => i.MembershipVacation) 
         .Distinct() 
         .Where(i => 
         i.Type == type && (
         i.Membership != null ? i.Membership.Username.Contains(model.sSearch, StringComparison.OrdinalIgnoreCase) : false 
         || i.Membership.Department != null ? i.Membership.Department.Name.Contains(model.sSearch, StringComparison.OrdinalIgnoreCase) : false 
         || i.StartDate.ToString().Contains(model.sSearch, StringComparison.OrdinalIgnoreCase) 
         || i.EndDate.ToString().Contains(model.sSearch, StringComparison.OrdinalIgnoreCase))) 
         .Skip(model.iDisplayStart) 
         .Take(model.iDisplayLength); 
       } 
      } 


      List<string[]> result = new List<string[]>(); 
      foreach (var item in list) 
      { 
       var waiting = item.MembershipVacationApproves.Count(i => i.State == UI.Vacation.ApproveState.Waiting) > 0; 
       var cancel = item.MembershipVacationApproves.Count(i => i.State == UI.Vacation.ApproveState.Cancel) > 0; 
       var approve = item.MembershipVacationApproves.Count(i => i.State == UI.Vacation.ApproveState.Approve) == item.MembershipVacationApproves.Count; 
       var edit = item.Membership.MembershipRelation != null ? item.Membership.MembershipRelation.OwnerID == UI.Helper.User.ID : false; 
       var canApprove = item.MembershipVacationApproves.Count(i => i.MembershipID == UI.Helper.User.ID) == 1; 


       StringBuilder name_link = new StringBuilder(), 
        durumu = new StringBuilder(), 
        islemler = new StringBuilder(); 

       if (item.Membership.Staff != null) 
       { 
        name_link.Append("<a href=" + this.Url.Action("Profile", "Staff", new { id = item.MembershipID }) + ">" + item.Membership.Username + "</a>"); 
       } 
       else 
       { 
        name_link.Append(item.Membership.Username); 
       } 
       if (!cancel) 
       { 
        if (approve) 
        { 
         if (DateTime.Now < item.StartDate) 
         { 
          durumu.Append("<small class='btn green-bg'>İstek onayladı.</small>"); 
         } 
         else 
         { 
          if (DateTime.Now > item.EndDate) 
          { 
           durumu.Append("<small class='btn green'>Kişi izinden dönmüş.</small>"); 
          } 
          else 
          { 
           durumu.Append("<small class='btn green'>Kişi izinde.</small>"); 
          } 
         } 
        } 
        else 
        { 
         durumu.Append("<small class='btn orange'>İstek onaylanması için bekleniyor.</small>"); 
        } 
       } 
       else 
       { 
        durumu.Append("<small class='btn red'>İstek iptal edilmiş</small>"); 
       } 

       islemler.Append("<div class='btn-group'>"); 
       islemler.Append("<a class='btn green' href='#' data-toggle='dropdown'><i class='icon-user'></i>İşlemler"); 
       islemler.Append("<i class='icon-angle-down'></i></a>"); 
       islemler.Append("<ul class='dropdown-menu'>"); 

       islemler.Append("<li><a href='" + this.Url.Action("RequestDetail", "Vacation", new { id = item.ID }) + "' data-toggle='modal' data-target='#'><i class='icon-search'>"); 
       islemler.Append("</i>İncele</a></li>"); 

       /*if (User.IsInRole("İzin Onaylama") || edit) 
       { 
        islemler += "<li><a href='" + this.Url.Action("Request", "Vacation", new { id = item.ID }) + "'><i class='icon-search'>"; 
        islemler += "</i>Düzenle</a></li>"; 
       }*/ 
       if (!(DateTime.Now > item.StartDate && approve) && canApprove) 
       { 
        islemler.Append("<li><a href=" + this.Url.Action("ApproveRequest", "Vacation", new { id = item.ID }) + "><i class='icon-ok'></i>Onayla</a></li>"); 
        islemler.Append("<li><a href=" + this.Url.Action("DeclinePage", "Vacation", new { id = item.ID }) + " data-toggle='modal' data-target='#'><i class='icon-remove'></i>Onaylama</a></li>"); 
       } 

       islemler.Append("</ul>"); 
       islemler.Append("</div>"); 

       result.Add(
        new string[] 
        { 
         name_link.ToString(), 
         item.PostDate.ToString(), 
         item.Membership.Department != null ? item.Membership.Department.Name : string.Empty, 
         item.StartDate.ToString(), 
         item.EndDate.ToString(), 
         durumu.ToString(), 
         islemler.ToString() 
        }); 
      } 

      var total = (DateTime.Now - startTime); 

      System.Diagnostics.Debug.WriteLine("total ms " + total.TotalMilliseconds); 

      return Json(new 
      { 
       sEcho = model.sEcho, 
       iTotalRecords = allEntries.Count(), 
       iTotalDisplayRecords = allEntries.Count(), 
       aaData = result 
      }, JsonRequestBehavior.AllowGet); 

     } 

    } 

최악의 일부가되어 있는지 확인 버튼 및 권한

에 대한 마지막 foreach는 과정

답변

1
나는 당신이 당신의 마지막 foreach 루프의 N + 1 SQL 쿼리 문제가 있음을 추측 할

: 다음 5 개 SQL 쿼리를 실행하면 list 구축을 목록의 각 항목

조언을 진단하고 해결하기 위해 :

  • MiniProfiler를 설치하고 데이터베이스를 프로파일을 활성화 - 당신은 SQL 쿼리 요청에 의해 촉발되고있는 볼 수, 그리고거야 당신은 어떤이있는 경우 중복 쿼리.
  • list에 대한 항목을 쿼리 할 때 EntityFramework의 Include 메서드를 사용하여로드 관련 데이터를 열심히로드하십시오. 이렇게하면 EF가 foreach 내에서 별도의 중복 검색어를 발행하지 않아도됩니다.
+0

수정했습니다. var에 대한 잘못된 코드를 작성했습니다. canApprove = item.MembershipVacationApproves.Count (i => i.MembershipID == UI.Helper.User.ID) == 1; UI.Helper.User는 매회 아무 것도 처리하지 않았습니다. 감사 ! – alim