-1

次のように、親 -> 子 -> 孫の関係に 3 つのデータ型があります。

Mission -> Activity -> Project

ここには、関係の親 ID が含まれています (つまり、「プロジェクト」には「アクティビティ」ID が含まれています)。ユーザーが「ミッション」をクリックして関連する「アクティビティ」を表示し、「アクティビティ」をクリックして関連する「プロジェクト」を表示できるように、jQuery のネストされたアコーディオン設定を生成するために使用するコードがいくつかあります。

私が持っているコードは、ページにアクセスしてデータベースからデータを取得し、ページに入力するまでに約 6 秒かかります。これは長すぎるので、可能な限りコードを最適化したいと考えています。miniprofiler (miniprofiler.com) を使用すると、データベースに対して 131 回の呼び出しが行われ、呼び出しが重複していることがわかりますが、その理由は確かです。

あなたが私に与えることができるどんな助けも大歓迎です!

すべてのデータを取得して整理するために使用する LINQ クエリ:

public IEnumerable<MissionWithActivities> GetTierTree()
{
var q = from mission in _context.tMissions
        join activity in _context.tActivities on mission.id equals activity.missionId
        join project in _context.tDefaultEventTypes on activity.id equals project.activityId
        where !project.isRemoved && project.defaultCategoryId == 4
        orderby mission.id, activity.id, mission.name
        select new DefaultEventType(project.tierLevel.TryParseEnum<GanttType>(GanttType.Unknown), DefaultCategoryRepository.CreateFrom(project.tDefaultCategory))
        {
            AllowNumericSuffix = project.allowNumericSuffix,
            AttachMilestoneMoniker = project.attachMilestoneMoniker,
            Description = project.description,
            Id = project.id,
            IsReadOnly = project.isReadOnly,
            IsSticky = project.isSticky,
            Name = project.name,
            Sid = project.sid,
            Style = project.style.TryParseEnum<GanttElementStyle>(GanttElementStyle.Unknown),
            TimeStamp = project.createdDT,
            UpdatedTimeStamp = project.updatedDT,
            Activity = new Activity { Id = activity.id, Name = activity.name, Mission = new Mission { Id = mission.id, Name = mission.name } }
        };
var q2 = q.GroupBy(
    e => e.Activity.Mission.Id,
    (mid, events) => new MissionWithActivities
    {
        Mission = events.First().Activity.Mission,
        Activities = events.GroupBy(
            e => e.Activity.Id,
            (aid, events2) => new ActivityWithEvents
            {
                Activity = events2.First().Activity,
                Events = events2
            })
    });
return q2.ToList();

}

最初にデータリストを作成し、次にネストされたアコーディオンを作成するために使用する分離コード:

public void SetTierTree(IEnumerable<MissionWithActivities> tierList)
{
dlMission.DataSource = tierList;
dlMission.DataBind();
}
public void dlMission_ItemDataBound(Object sender, DataListItemEventArgs e)
{
DataListItem item = e.Item;
MissionWithActivities mwa = (MissionWithActivities)item.DataItem;
var dlActivity = (DataList)item.FindControl("dlActivity");
dlActivity.DataSource = mwa.Activities;
dlActivity.DataBind();
var i = 0;
foreach (var project in mwa.Activities)
{
    DataListItem pItem = dlActivity.Items[i];
    var lbCreateNewProject = (LinkButton)pItem.FindControl("lbCreateNewProject");
    lbCreateNewProject.CommandArgument = project.Activity.Id.ToString();
    var dlProject = (DataList)pItem.FindControl("dlProject");
    dlProject.DataSource = project.Events;
    dlProject.DataBind();
    i++;
    var j = 0;
    foreach (var data in project.Events)
    {
        DataListItem lblItem = dlProject.Items[j];
        var lbEditProject = (LinkButton)lblItem.FindControl("lbEditProject");
        var lbRemoveProject = (LinkButton)lblItem.FindControl("lbRemoveProject");
        lbEditProject.CommandArgument = data.Id.ToString();
        lbRemoveProject.CommandArgument = data.Id.ToString();
        j++;
    }
}
}

これは、jQuery を含む .aspx ページです (.net を削除していないため、実行されません) が、閲覧用にコードを含めたいと思いました。

$(document).ready(function () {
        $("html").addClass("js");
        $(".row").mouseover(function () { $(this).addClass("over"); }).mouseout(function () { $(this).removeClass("over"); });
        $('h5').click(function () { $(this).prev(".heading_add").toggle(); });
        $(".row:even").addClass("alt");
        $.fn.accordion.defaults.container = false;
        $(function () {
            $("#acc1").accordion({
                el: ".h",
                head: "h4, h5",
                next: "div",
                initShow: "none"
            });
            $("html").removeClass("js");
        });
    });
<div id="main">
        <ul id="acc1" class="accordion">
        <asp:DataList ID="dlMission" runat="server" style="width:600px;">
        <ItemTemplate>
            <li>
                <h4><%# Eval("Mission.Name") %></h4>
                <div class="inner">
                    <ul>
                    <asp:DataList ID="dlActivity" runat="server">
                    <ItemTemplate>
                        <li>
                          <asp:LinkButton ID="lbCreateNewProject" CausesValidation="false" CssClass="heading_add" runat="server" Text="[ + ] Add New Project Type" OnCommand="lbCreateNewProject_OnCommand" />
                          <h5><%# Eval("Activity.Name") %></h5>
                          <div class="inner">
                          <asp:DataList ID="dlProject" runat="server">
                          <ItemTemplate>
                            <div class="row">
                              <%# Eval("Name") %><div class="action_buttons"><asp:LinkButton ID="lbEditProject" CausesValidation="false" runat="server" Text="Edit" OnCommand="lbEditProject_OnCommand" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<asp:LinkButton ID="lbRemoveProject" CausesValidation="false" runat="server" Text="Remove" OnCommand="lbRemoveProject_OnCommand" /></div><br />
                            </div>
                          </ItemTemplate>
                          </asp:DataList>
                          </div>
                        </li>
                    </ItemTemplate>
                    </asp:DataList>
                    </ul>
                </div>
            </li>
        </ItemTemplate>
        </asp:DataList>
        </ul>
    </div>

興味深いことに、これを行うために jQuery.nestedAccordion.js プラグインを使用しています。

4

1 に答える 1

0

私が経験していた速度低下の主な原因は、LINQ の動作に関係していることがわかりました。私の主な問題は、LINQクエリでこれでした:

DefaultCategoryRepository.CreateFrom(project.tDefaultCategory)

CreateFrom 関数により、LINQ が DefaultCategory に関連付けられたすべてのデータを大量に取得していました。私は、LINQ がすべてのリレーションシップをツリーのずっと下まで取得し、それが使用されているかどうかに関係なく返すことを知りませんでした。詳細については、ここで読むことができます。

http://msdn.microsoft.com/en-us/library/bb738633(v=vs.100).aspx

MiniProfiler はまだ重複呼び出しが 131 回行われていると言っていますが、それは .Net の実行方法に関係していると思います。

これが誰かを助けることを願っています!

于 2013-01-30T17:23:53.810 に答える