【发布时间】:2013-05-06 20:45:46
【问题描述】:
下面是我在我的 ASP MVC 3 视图中为他们的typeahead.js 插件使用的 jQuery 代码。
$('#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
};
编辑
我将查询更改为下面的这个结构,但是现在我收到了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();
【问题讨论】:
-
对您的 SQL 查询进行基准测试。
Data = (agents.Union(corps).ToArray())...行是执行查询的内容,所以它在那里被延迟是有道理的。 -
为什么
where a.FirstName.Contains(term) || a.LastName.Contains(term) || a.CorporateName.Contains(term)的选择还不够? -
我很好奇这会生成什么样的 SQL,以及为什么你要从 SQL 语法转向构造函数语法(或任何它的名字),而不是在后者中全部完成并避免 AsEnumerable在进行选择投影之前。我想知道这种格式是否导致投影未应用于 SQL 调用,但后来评估意味着返回的数据多于必要的数据。
-
不太清楚你所说的“基准测试”我的 SQL 查询是什么意思。如果您的意思是与我们在此站点上进行的其他操作进行比较,则等待时间甚至无法比较。大多数都在几毫秒内完成,但这需要将近一分钟。
-
我认为他的意思是从该查询中获取生成的 SQL 语句并在您的 SQL DB 上运行它以查看执行需要多长时间。实际上,生成的 SQL 可能足以发现问题,但也无妨。他们可能会建议您需要索引等。
标签: asp.net-mvc asp.net-mvc-3 jquery bootstrap-typeahead