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();
答
诚心诚意地提出这是多么容易被重用,你可能会考虑做所有这些都在存储过程中,只需使用“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)
});
基准您的SQL查询。 'Data =(agents.Union(corps).ToArray())...'这行是执行查询的内容,所以它在这里被延迟了。 – 2013-05-06 20:51:44
为什么没有选择'where a.FirstName.Contains(term)|| a.LastName.Contains(term)|| a.CorporateName.Contains(term)'足够吗? – 2013-05-06 21:17:01
我很好奇这是什么样的SQL产生,以及为什么你要从SQL语法到构造函数语法(或者其他所谓的),而不是在后者中做所有事情,并在做选择投影之前避免使用AsEnumerable。我想知道这种格式是否会导致投影不被应用到SQL调用中,但是后来的评估意味着更多的数据会回来。 – 2013-05-06 21:19:15