0

我有一个使用 DataTables 的项目。它作为ajax请求工作。它在 8-12 秒内完成。我需要优化这段代码,但我不知道如何。字符串处理是最糟糕的部分。

    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 过程

4

1 回答 1

1

我猜你在最后一个foreach循环中有一个 N+1 SQL 查询问题:你list为列表中的每个项目构建然后触发 5 个 SQL 查询。

诊断和修复建议:

  • 安装MiniProfiler并启用数据库分析 - 然后您将能够查看请求触发了哪些 SQL 查询,以及是否有任何重复查询。
  • 利用 EntityFramework 的Include方法,在您查询list. 这将使 EF 不必在foreach.
于 2013-07-30T07:53:17.803 回答