2010-07-26 24 views
0

在我的web應用程序中,我正在加載一個頁面,該頁面可以在表中加載多達8000行或更多行,每行都有自己的下拉列表。這第一個過程證明是非常低效的,但我被要求這樣做。加載行的代碼如下:加速頁面加載和信息處理

<tbody> 
     <% var i = 0; 



      foreach (var row in Model) 
      { 
       var comp = "ok"; 
       if (row.LidExpected != (string.IsNullOrEmpty(row.LidObtained) ? null : row.LidObtained) || row.QuantityExpected != row.QuantityObtained) 
       { 
        comp = "ko"; 
       } 
       %> 
     <tr class="child_row <%= comp %>"> 
      <input type="hidden" name="Goods.index" value="<%= i %>" /> 
      <td class="field <%= InventoryGoods.Metadata.Gid.CssClass %>"> 
       <%-- <%= Html.Encode(row.Gid) %>--%> 
       <%--http://tecnicos.urbanos.com/Goods/Details/... --%> 
       <%= Html.ActionLink(row.Gid, "Details", "Goods", new {id = row.Gid}, null) %> 
       <%= Html.Hidden(String.Format("Record[{0}].Gid", i), row.Gid) %> 
      </td> 
      <td class="field <%= InventoryGoods.Metadata.LidExpected.CssClass %>"> 
       <%= Html.Encode(row.LidExpected) %> 
       <%= Html.Hidden(string.Format("Record[{0}].LidExpected", i), row.LidExpected)%> 
      </td> 
      <td class="fieldRight <%= InventoryGoods.Metadata.QuantityExpected.CssClass %>"> 
       <%= Html.Encode(row.QuantityExpected) %> 
       <%= Html.Hidden(string.Format("Record[{0}].QuantityExpected", i), row.QuantityExpected)%> 
      </td> 
      <td class="field <%= InventoryGoods.Metadata.LidObtained.CssClass %>"> 
       <%= Html.Encode(row.LidObtained) %> 
       <%= Html.Hidden(string.Format("Record[{0}].LidObtained", i), row.LidObtained)%> 
      </td> 
      <td class="fieldRight <%= InventoryGoods.Metadata.QuantityObtained.CssClass %>"> 
       <%= Html.Encode(row.QuantityObtained) %> 
       <%= Html.Hidden(string.Format("Record[{0}].QuantityObtained", i), row.QuantityObtained)%> 
      </td> 
      <%if (int.Parse(state.ToString()) == (int)InventoryStateEnum.Closed || int.Parse(state.ToString()) == (int)InventoryStateEnum.Verified) 
       { %> 
      <td class="field <%= InventoryGoods.Metadata.Action.CssClass %>"> 
       <%       
        switch (row.Action) 
        { 
         case (int)InventoryGoodsActionEnum.AdjustQuantity: %> 
          <%= Html.DropDownList(String.Format("Record[{0}].Action", i), new[] 
        { 
         new SelectListItem { Text= "Ajustar Quantidade", Value= ((int)InventoryGoodsActionEnum.AdjustQuantity).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustQuantity == row.Action ? true : false},       
         new SelectListItem { Text= "Ignorar", Value= ((int)InventoryGoodsActionEnum.Ignore).ToString(), Selected= (int)InventoryGoodsActionEnum.Ignore == row.Action ? true : false}, 
        })%> 
         <%  break; 
         case (int)InventoryGoodsActionEnum.AdjustLocation: %> 
          <%= Html.DropDownList(String.Format("Record[{0}].Action", i), new[] 
        { 

         new SelectListItem { Text= "Relocalizar", Value= ((int)InventoryGoodsActionEnum.AdjustLocation).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustLocation == row.Action ? true : false},       
         new SelectListItem { Text= "Ignorar", Value= ((int)InventoryGoodsActionEnum.Ignore).ToString(), Selected= (int)InventoryGoodsActionEnum.Ignore == row.Action ? true : false}, 
        })%> 
          <% break; 
         case (int)InventoryGoodsActionEnum.AdjustStockType: %> 
          <%= Html.DropDownList(String.Format("Record[{0}].Action", i), new[] 
        {       
         new SelectListItem { Text= "Ajustar Tipo de Stock", Value = ((int)InventoryGoodsActionEnum.AdjustStockType).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustStockType == row.Action ? true : false},       
         new SelectListItem { Text= "Ignorar", Value= ((int)InventoryGoodsActionEnum.Ignore).ToString(), Selected= (int)InventoryGoodsActionEnum.Ignore == row.Action ? true : false}, 
        })%> 
         <% break; 
         case (int)InventoryGoodsActionEnum.AdjustQuantityLocation: %> 
          <%= Html.DropDownList(String.Format("Record[{0}].Action", i), new[] 
        { 
         new SelectListItem { Text= "Ajustar Quantidade", Value= ((int)InventoryGoodsActionEnum.AdjustQuantity).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustQuantity == row.Action ? true : false}, 
         new SelectListItem { Text= "Relocalizar", Value= ((int)InventoryGoodsActionEnum.AdjustLocation).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustLocation == row.Action ? true : false}, 
         new SelectListItem { Text= "Ajustar Quantidade e Relocalizar", Value= ((int)InventoryGoodsActionEnum.AdjustQuantityLocation).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustQuantityLocation == row.Action ? true : false},             
         new SelectListItem { Text= "Ignorar", Value= ((int)InventoryGoodsActionEnum.Ignore).ToString(), Selected= (int)InventoryGoodsActionEnum.Ignore == row.Action ? true : false}, 
        })%> 
          <% break; 
         case (int)InventoryGoodsActionEnum.AdjustQuantityStockType: %> 
          <%= Html.DropDownList(String.Format("Record[{0}].Action", i), new[] 
        { 
         new SelectListItem { Text= "Ajustar Quantidade", Value= ((int)InventoryGoodsActionEnum.AdjustQuantity).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustQuantity == row.Action ? true : false},       
         new SelectListItem { Text= "Ajustar Tipo de Stock", Value = ((int)InventoryGoodsActionEnum.AdjustStockType).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustStockType == row.Action ? true : false}, 
         new SelectListItem { Text= "Ajustar Quantidade e Tipo de Stock", Value = ((int)InventoryGoodsActionEnum.AdjustQuantityStockType).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustQuantityStockType == row.Action ? true : false},       
         new SelectListItem { Text= "Ignorar", Value= ((int)InventoryGoodsActionEnum.Ignore).ToString(), Selected= (int)InventoryGoodsActionEnum.Ignore == row.Action ? true : false}, 
        })%> 
         <% break; 
         case (int)InventoryGoodsActionEnum.AdjustLocationStockType: %> 
          <%= Html.DropDownList(String.Format("Record[{0}].Action", i), new[] 
        { 

         new SelectListItem { Text= "Relocalizar", Value= ((int)InventoryGoodsActionEnum.AdjustLocation).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustLocation == row.Action ? true : false},       
         new SelectListItem { Text= "Ajustar Tipo de Stock", Value = ((int)InventoryGoodsActionEnum.AdjustStockType).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustStockType == row.Action ? true : false},       
         new SelectListItem { Text= "Ajustar Tipo de Stock e Relocalizar", Value = ((int)InventoryGoodsActionEnum.AdjustLocationStockType).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustLocationStockType == row.Action ? true : false},       
         new SelectListItem { Text= "Ignorar", Value= ((int)InventoryGoodsActionEnum.Ignore).ToString(), Selected= (int)InventoryGoodsActionEnum.Ignore == row.Action ? true : false}, 
        })%> 
         <% break; 
         case (int)InventoryGoodsActionEnum.AdjustQuantityLocationStockType: %> 
          <%= Html.DropDownList(String.Format("Record[{0}].Action", i), new[] 
        { 
         new SelectListItem { Text= "Ajustar Quantidade", Value= ((int)InventoryGoodsActionEnum.AdjustQuantity).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustQuantity == row.Action ? true : false}, 
         new SelectListItem { Text= "Relocalizar", Value= ((int)InventoryGoodsActionEnum.AdjustLocation).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustLocation == row.Action ? true : false}, 
         new SelectListItem { Text= "Ajustar Quantidade e Relocalizar", Value= ((int)InventoryGoodsActionEnum.AdjustQuantityLocation).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustQuantityLocation == row.Action ? true : false},       
         new SelectListItem { Text= "Ajustar Tipo de Stock", Value = ((int)InventoryGoodsActionEnum.AdjustStockType).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustStockType == row.Action ? true : false}, 
         new SelectListItem { Text= "Ajustar Quantidade e Tipo de Stock", Value = ((int)InventoryGoodsActionEnum.AdjustQuantityStockType).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustQuantityStockType == row.Action ? true : false}, 
         new SelectListItem { Text= "Ajustar Tipo de Stock e Relocalizar", Value = ((int)InventoryGoodsActionEnum.AdjustLocationStockType).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustLocationStockType == row.Action ? true : false}, 
         new SelectListItem { Text= "Ajustar Quantidade, Tipo de Stock e Relocalizar", Value = ((int)InventoryGoodsActionEnum.AdjustQuantityLocationStockType).ToString(), Selected= (int)InventoryGoodsActionEnum.AdjustQuantityLocationStockType == row.Action ? true : false}, 
         new SelectListItem { Text= "Ignorar", Value= ((int)InventoryGoodsActionEnum.Ignore).ToString(), Selected= (int)InventoryGoodsActionEnum.Ignore == row.Action ? true : false}, 
        })%> 
         <% break; 
        } 


       %> 
       <%= Html.Hidden(string.Format("db_Action[{0}]", i), row.Action)%> 
      </td> 
      <td> 
       <a title="Apagar Evento" id="delete_Event" class="ui-widget ui-state-default ui-icon ui-icon-trash"> 
       </a> 
      </td> 
      <td class="field <%= InventoryGoods.Metadata.ActionOn.CssClass %>" id="dateCell"> 
       <span id="ActionOn_<%= i %>"> 
        <%= Html.Encode(row.ActionOn.HasValue ? Html.FormatDateTime(row.ActionOn.Value) : Html.Encode(""))%></span> 
       <%= Html.Hidden(String.Format("Record[{0}].ActionOn", i), row.ActionOn.HasValue ? row.ActionOn.Value : new DateTime())%> 
      </td> 
      <% } %> 
      <%= Html.Hidden("lineVal", i) %> 
      <% i++; 
      } %> 
     </tr> 
    </tbody> 

所以這是所有問題的根源。 下一個問題是當我需要將這些數據發送回服務器時,這當然也會佔用很多時間。我不知道有什麼辦法讓它更快,因爲現在需要大約8或9分鐘才能將9000行發送回服務器。

問題仍然存在,當我用這些行的批更新,具體如下:

public void UpdateInventoryGoods(List<InventoryGoods> list, int id) 
     { 
      //int index = 0; 

      var query = from inventoryGoods in context.InventoryGoods 
         where inventoryGoods.ParentId == id 
         select inventoryGoods; 

      List<InventoryGoods> goodsList = query.ToList(); 
      var memmoryInventoryGoodsEvent = context.InventoryGoodsEvents.ToList();//obter apenas o do Id 

      using (var scope = new TransactionScope()) 
      { 
       var events = from g in context.GoodsEvent 
          select g; 
       List<GoodsEvent> goodsEventList = events.ToList(); 

       foreach (InventoryGoods i in list) 
       { 
        foreach (InventoryGoods e in goodsList) 
        { 
         //if (index == 30) 
         //{ 
         // index = 0; 
         // context.SubmitChanges(); 
         //} 
         var eventId = getEventId(e.Id, memmoryInventoryGoodsEvent); 
         if (e.Gid == i.Gid && !eventId.HasValue && !e.ActionOn.HasValue) 
         { 
          e.Action = i.Action; 

         } 
         else if ((e.Gid == i.Gid && eventId.HasValue) && (e.Action != i.Action || i.ActionOn == DateTime.MinValue)) 
         { 
          e.Action = i.Action; 
          e.ActionOn = null; 



          var inventoryGoodsEventsList = memmoryInventoryGoodsEvent.Where(x => x.InventoryGood == e.Id); 





          foreach (InventoryGoodsEvents goodsEvent in inventoryGoodsEventsList) 
          { 
           context.InventoryGoodsEvents.DeleteOnSubmit(goodsEvent); 

           foreach (GoodsEvent ge in goodsEventList) 
           { 
            if (ge.Id == goodsEvent.EventId) 
            { 
             ge.IsDeleted = true; 
             ge.DeletedOn = DateTime.Now; 
             ge.DeletedBy = System.Web.HttpContext.Current.User.Identity.Name; 
            } 
           } 
          } 




         } 
         //++index; 
        } 
       } 
       context.SubmitChanges(); 
       scope.Complete(); 
      } 

     } 

    public int? getEventId(int InventoryGood,List<InventoryGoodsEvents> memmoryList) 
     { 
      //var firstinventoryGoodsEvents = context.InventoryGoodsEvents.Where(i => i.InventoryGood == InventoryGood).FirstOrDefault(); 
      var firstinventoryGoodsEvents = memmoryList.Where(i => i.InventoryGood == InventoryGood).FirstOrDefault(); 

      if (firstinventoryGoodsEvents != null && firstinventoryGoodsEvents.InventoryGood > 0) 
      { 
       return firstinventoryGoodsEvents.InventoryGood; 

      } 
      else 
      { 
       return null; 
      } 
     } 

在雙重的foreach迭代的我和e變量上面的意思是我在查看了該行的行數據庫。我運行它們以發現任何差異,如果有差異,請更新它們。但是所有這些過程都證明速度太慢,我真的需要快速改進。特別是雙重foreach迭代,我無法找到更好的解決方案。

那麼你能幫助我嗎?

編輯:我固定至少通過使用詞典的更新方法和逃避雙重的foreach迭代我在我前面的代碼做這樣的:

public void UpdateInventoryGoods(List<InventoryGoods> list, int id) 
    { 
     //int index = 0; 

     var query = from inventoryGoods in context.InventoryGoods 
        where inventoryGoods.ParentId == id 
        select inventoryGoods; 

     Dictionary<string, InventoryGoods> goodsDictionary = query.ToDictionary(p => p.Gid); 
     var memmoryInventoryGoodsEvent = (from c in context.InventoryGoodsEvents 
             join a in context.InventoryGoods on c.InventoryGood equals a.Id 
             where a.ParentId == id 
             select c).ToList();//obter apenas o do Id 

     using (var scope = new TransactionScope()) 
     { 
      var events = from g in context.GoodsEvent 
         select g; 

      Dictionary<int, GoodsEvent> goodsEventDictionary = events.ToDictionary(p => p.Id); 

      //List<GoodsEvent> goodsEventList = events.ToList(); 

      foreach (InventoryGoods i in list) 
      { 

       var eventId = getEventId(i.Id, memmoryInventoryGoodsEvent); 

       var objectToUpdate = goodsDictionary[i.Gid]; 


       if (!eventId.HasValue && !objectToUpdate.ActionOn.HasValue) 
       { 
        objectToUpdate.ActionOn = i.ActionOn; 
        continue; 
       } 
       else if (eventId.HasValue && objectToUpdate.Action != i.Action || i.ActionOn == DateTime.MinValue) 
       { 
        objectToUpdate.Action = i.Action; 
        objectToUpdate.ActionOn = null; 

        var inventoryGoodsEventsList = memmoryInventoryGoodsEvent.Where(x => x.InventoryGood == objectToUpdate.Id); 

        foreach (InventoryGoodsEvents goodsEvent in inventoryGoodsEventsList) 
        { 
         context.InventoryGoodsEvents.DeleteOnSubmit(goodsEvent); 

         var eventToUpdate = goodsEventDictionary[goodsEvent.EventId]; 

           eventToUpdate.IsDeleted = true; 
           eventToUpdate.DeletedOn = DateTime.Now; 
           eventToUpdate.DeletedBy = System.Web.HttpContext.Current.User.Identity.Name;        
        } 

       } 
      } 
      context.SubmitChanges(); 
      scope.Complete(); 
     } 

    } 
+0

我很樂意介紹這些信息,但我做不到,因爲這些都是我的訂單。信息必須一次顯示......我知道這不是可取的,但我需要至少讓這個過程不那麼痛苦...... – Hallaghan 2010-07-26 14:24:47

+0

祝你好運。當DOM元素太多時,瀏覽器開始barfing。僅僅因爲管理層要求這並不意味着它是可行的。 http://developer.yahoo.com/performance/rules.html#min_dom – 2010-07-26 14:33:14

+0

這是真的......但無論我回頭說什麼,這些都是要求,我不能做任何事情,只能遵守他們。無論你有什麼可以說,這將有助於,我感謝。即使你只是在雙倍的幫助下... – Hallaghan 2010-07-26 14:35:31

回答

5

兩個選項:

  1. 說服顧客認爲分頁是必要的或性能將受到影響。向他展示其他已建立的網站是如何做的。
  2. 使用AJAX。只加載在屏幕上可以看到的內容,選擇jQuery scroll plugin,當用戶滾動時用AJAX加載缺失的部分。有點像Google Images。你也可以嘗試一些out of the box controls來避免繁重的工作。

無論你選擇什麼選項,修復視圖代表當前使用助手的標記湯。

2

頁列表。無論如何,沒有人可以一次處理8000行。對你的列表進行分頁,提供過濾器來幫助你的用戶找到你想要的東西,並且你可以大量減少發送的數據量。

+4

最重要的是,列出你的列表。也可以考慮分頁。 – 2010-07-26 14:19:59

1

8000行?你應該放棄這個想法並實施某種分頁。無論應用程序如何,向用戶顯示8000行都是無用的。我使用mvccontrib grid具有分頁功能。

0

不這樣做。即使可以讓服務器快速發送,瀏覽器也不會喜歡渲染那麼多的信息。任何顯示這麼多行的瀏覽器都會在客戶端上運行得非常慢,滾動會變得不穩定,並且通常無法使用。

我建議要麼分頁信息,要麼更好地過濾信息,只顯示用戶感興趣的內容,任何用戶都不會一次對那麼多數據感興趣。

+0

請在上面閱讀我的辦公室的要求... – Hallaghan 2010-07-26 15:40:06

0

如果您只爲頁面上的每種類型的下拉列表以json格式呈現一次下拉菜單的數據項,可能會有所幫助的一個選項。然後使用javascript在客戶端創建並填充所有選定的ddl。它將爲每個渲染的行保存所有冗餘的冗餘數據傳輸。您只需在構建選擇時存儲將在每行中選擇的值。這只是一個想法,我還沒有嘗試過,這可能會導致客戶端只是等待JavaScript來做它的事情。

此外,更新數據,是ajax的一種可能性,只是要求每個下拉的變化正確的變化發生?

+0

它不能完成,因爲只有在用戶單擊保存按鈕時纔會進行更改。 – Hallaghan 2010-07-26 16:43:51

0

第一個問題是,慢代碼在哪裏?

關於服務器處理時間,網絡傳輸或瀏覽器渲染時間?

在某些情況下,大型HTML表格在IE(甚至IE8)上速度太慢。使用CSS「table-layout: fixed」可能對此有所幫助。