Controller.Json函数对于IQueryable来说很慢

时间:2015-12-24 13:57:24

标签: json asp.net-mvc

我有一个mvc控制器动作,返回json,大约需要2秒,我希望这个速度更快,不到1秒。我正在使用控制器动作,并发现返回json的行很慢,直到那里执行的时间少于100毫秒。 是因为我使用IQueryable接口实际的sql到linq查询到达该行,并且只执行了DB查询并且它执行类似" toList()"的操作。我想知道那里到底发生了什么? 或者Controller.Json函数通常很慢,我可以使用更好的东西吗?

 public ActionResult GetItems()
{
    IQueryable<Item> Items = default(IQueryable<Item>);
      Items = myComponent.getItems(); //returns IQueryable
     var result = Items.OrderByDescending(m => m.category).ThenBy(m => m.order);
      return Json(result, JsonRequestBehavior.AllowGet);
  }

1 个答案:

答案 0 :(得分:4)

有可能有两个地方可以调整:

  1. IQuerable it self
  2. Controller.Json的序列化方法
  3. 对于IQuerable查询,您可以尝试使用sql profiler或尝试调用ToList(),然后返回它以查看它需要多长时间并可能对其进行优化 (没有更多的查询知识,我无法帮助你。)

    但是对于第二部分,您可以尝试使用像Json.Net

    这样的库来序列化结果

    source代码开始,当您调用Json()时,可以看到Mvc使用JavaScriptSerializer来执行json序列化。 (你也可以通过查看源代码看看实际发生了什么)

    从json.net网站的比较图表来看,JavaScriptSerializer的表现非常糟糕。 ![enter image description here

    所以你可以尝试使用Json.Net实现自己的JsonActionResult,下面是一些示例代码:

    来自:Using JSON.NET to return ActionResult

    在您的控制器(或基本控制器)

    protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding, JsonRequestBehavior behavior)
    {
        return new JsonNetResult
        {
            Data = data,
            ContentType = contentType,
            ContentEncoding = contentEncoding,
            JsonRequestBehavior = behavior
        };
    }
    

    JsonNetResult的定义:

    public class JsonNetResult : JsonResult
    {
        public JsonNetResult()
        {
            Settings = new JsonSerializerSettings
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
            };
        }
    
        public JsonSerializerSettings Settings { get; private set; }
    
        public override void ExecuteResult(ControllerContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");
            if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
                throw new InvalidOperationException("JSON GET is not allowed");
    
            HttpResponseBase response = context.HttpContext.Response;
            response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType;
    
            if (this.ContentEncoding != null)
                response.ContentEncoding = this.ContentEncoding;
            if (this.Data == null)
                return;
    
            var scriptSerializer = JsonSerializer.Create(this.Settings);
    
            using (var sw = new StringWriter())
            {
                scriptSerializer.Serialize(sw, this.Data);
                response.Write(sw.ToString());
            }
        }
    }
    
相关问题