2013-01-23 99 views
-1

我有一個父三種數據類型 - >子 - >孫關係如下:優化填充嵌套手風琴

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插件來做到這一點。

+0

與其讓131個DB調用只是在一次調用中拉下所有數據,然後通過查詢內存數據結構來構建樹。 – Servy

+0

@Servy從我的LINQ聲明中發出131個DB調用嗎?我在猜測,也許每次我使用LINQ時,它都會再次訪問數據庫,但我無法確定。這聽起來正確嗎? – Omni

+0

既然你說過,''我可以看到它打了131次調用數據庫,並且有很多重複調用,但是**我確定爲什麼**。「顯然你已經確定它爲什麼會發生並且不需要幫助接着就,隨即。 – Servy

回答

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運行做事的方式去做,如果我通過步驟該代碼只會觸及查詢一次,所以仍然可以解決這個問題。

希望這可以幫助別人!