jQuery/Ajax调用需要花费很多时间才能完成

jQuery/Ajax调用需要花费很多时间才能完成

问题描述:

下面是我在我的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

诚心诚意地提出这是多么容易被重用,你可能会考虑做所有这些都在存储过程中,只需使用“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) 
    });