2013-05-06 171 views
0

下面是我在我的ASP MVC 3視圖中爲他們的typeahead.js插件使用的jQuery代碼。jQuery/Ajax調用需要花費很多時間才能完成

 $('#typeahead').typeahead({ 
      source: function (term, process) { 
       var url = '@Url.Content("~/Agent/GetAgents")'; 
       var agents = []; 
       map = {}; 

       return ($.getJSON(url, { term: term }, function (data) { 
        $.each(data, function (i, item) { 
         map[item.Name] = item; 
         agents.push(item.Name); 
        }); 

        process(agents); 
       })); 
      }, 
      highlighter: function (item) { 
       var p = map[item]; 
       var display = '' 
          + "<div class='typeahead_wrapper'>" 
          + "<div class='typeahead_labels'>" 
          + "<div class='typeahead_primary'>" + p.Name + </div> 
          + "<i>LastFour:</i>" + p.LastFour + "</div>" 
          + "<div class='typeahead_third'>" + "<i>Agent IDs:</i> " + p.AgentIds + "</div>" 
          + "</div>" 
          + "</div>"; 

       return display; 
      }, 
      updater: function (item) { 
       window.location.href = ("/Agent/Details/" + map[item].sNumber);      
      }    
     }); 

代碼在控制器中調用此方法GetAgents。整個過程完全符合它的要求,但這需要幾乎整整一分鐘的時間。

[HttpGet] 
    public JsonResult GetAgents(string term) 
    { 
     term = term.ToUpper(); 

     var agents = (from a in db.Agent 
         where a.FirstName.Contains(term) || 
          a.LastName.Contains(term) 
         select a).AsEnumerable() 
          .Select(x => new 
          { 
           Name = x.FirstName + " " + x.LastName, 
           sNumber = x.sNumber, 
           LastFour = x.DisplayTaxId, 
           AgentIds = String.Join(", ", from b in db.sNumberToAgentId 
                  where b.sNumber == x.sNumber 
                  select b.AgentId) 
          }); 

     var corps = (from a in db.Agent 
         where a.CorporateName.Contains(term) 
         select a).AsEnumerable() 
         .Select(x => new 
         { 
          Name = x.FirstName + " " + x.LastName, 
          sNumber = x.sNumber, 
          LastFour = x.DisplayTaxId, 
          AgentIds = String.Join(", ", from b in db.sNumberToAgentId 
                 where b.sNumber == x.sNumber 
                 select b.AgentId) 
         }); 

     return new JsonResult() 
     { 
      Data = (agents.Union(corps).ToArray()), 
      JsonRequestBehavior = JsonRequestBehavior.AllowGet 
     }; 
    } 

單步執行代碼,麻煩似乎是在這部分。有沒有人知道加快這種呼叫的方式,或者爲什麼會發生這種情況?

 return new JsonResult() 
     { 
      Data = (agents.Union(corps).ToArray()), 
      JsonRequestBehavior = JsonRequestBehavior.AllowGet 
     }; 

編輯

我改變了我的查詢,以低於這個strucutre,但現在我得到一個OutOfMemory Exception

 var agents = (from a in db.Agent 
        from b in db.sNumberToAgentId 
        join b in db.sNumberToAgentId on a.sNumber equals b.sNumber into apm 
        where a.FirstName.Contains(term) || a.LastName.Contains(term) 
        select new 
           { 
            Name = a.FirstName + " " + a.LastName, 
            sNumber = a.sNumber, 
            LastFour = a.DisplayTaxId, 
            AgentIds = b.AgentId 
           }).ToList(); 
+2

基準您的SQL查詢。 'Data =(agents.Union(corps).ToArray())...'這行是執行查詢的內容,所以它在這裏被延遲了。 – 2013-05-06 20:51:44

+0

爲什麼沒有選擇'where a.FirstName.Contains(term)|| a.LastName.Contains(term)|| a.CorporateName.Contains(term)'足夠嗎? – 2013-05-06 21:17:01

+0

我很好奇這是什麼樣的SQL產生,以及爲什麼你要從SQL語法到構造函數語法(或者其他所謂的),而不是在後者中做所有事情,並在做選擇投影之前避免使用AsEnumerable。我想知道這種格式是否會導致投影不被應用到SQL調用中,但是後來的評估意味着更多的數據會回來。 – 2013-05-06 21:19:15

回答

0

誠心誠意地提出這是多麼容易被重用,你可能會考慮做所有這些都在存儲過程中,只需使用「term」參數調用它即可。

如果這不可行,我建議你看看你的數據源是否有很多列 - 你當前的語法可能不適用於優化的SQL。通常,您的「選擇」可以作爲投影應用,以僅回收要從中提取數據的列。

你可以試試這個,但它沒有經過測試。我不能立即想到提前做聯合的語法來消除選擇投影中的子查詢,但也許另一個人可以幫助解決這個問題。

var results = db.Agent 
    .Where(a => a.CorporateName.Contains(term) || a.FirstName.Contains(term) || a.LastName.Contains(term)) 
    .Select(x => new { 
    Name = x.FirstName + " " + x.LastName, 
    sNumber = x.sNumber, 
    LastFour = x.DisplayTaxId, 
    AgentIds = String.Join(", ", from b in db.sNumberToAgentId 
           where b.sNumber == x.sNumber 
           select b.AgentId) 
    }); 
相關問題