0

下面是我在我的 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();
4

1 回答 1

0

老实说,考虑到重用它的可能性,您可能会考虑在存储过程中执行所有这些操作,并使用您的“术语”参数调用它。

如果这不可行,我建议您查看您的数据源是否有很多列 - 您当前的语法可能不适合优化的 SQL。通常,您的 Select 可以用作投影,以仅带回您从中提取数据的列。

你可以试试这个,但它未经测试。我无法立即想到提前进行连接以消除 Select 投影中的子查询的语法,但也许其他人可以提供帮助。

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)
  });
于 2013-05-06T21:30:06.390 回答