首页 > 解决方案 > Kendo 方法 ToDataSourceResult 为大量记录提供超时异常

问题描述

我正在使用 Kendo Grid,如下所示:

Html.Kendo().Grid<MyViewModel>()
.Name("grid")
.Columns(c => c.AutoGenerate(false))
.Filterable(f =>
{
    //coding for filteration
})
.Selectable(selectable => selectable.Mode(GridSelectionMode.Single))
.Reorderable(r => r.Columns(true))
.Pageable(pager => pager
    .Refresh(true)
    //coding for pages
)
.Sortable().Selectable(selectable => selectable.Mode(GridSelectionMode.Multiple))
.Scrollable(s => s.Height(450))
.Filterable()
.Resizable(r => r.Columns(true))
.DataSource(dataSource => dataSource.Ajax()
    .Events(ev => ev.RequestEnd("onRequestEnd"))
    .Sort(sort => { sort.Add(model => model.Date).Descending(); })
    .Filter(f => f.Add(model => model.SerialNo).IsEqualTo((this.Session["Id"] as MyModel).SerialNo)) // Applying Custom Filter
    .PageSize(10)
    .ServerOperation(true)
    .Read(read => read.Action("Read", "Controller").Data("Grid_Index_additionalData")))
 .Events(events => events.DataBound("onDataBound"))
 .Render();

控制器中的代码:

    [OutputCache(Duration = 0, VaryByParam = "None")]
    public ActionResult Read([DataSourceRequest]DataSourceRequest request, string searchBox)
    {
        IQueryable<MyViewModel> filteredResult;

        var collection1 = manager.Model1SelectAll();
        var collection2 = manager.Model2SelectAll();

        filteredResult =    from c1 in collection1
                            join c2 in collection2
                          on c1.SerialNo equals c2.SerialNo 
                              select new MyViewModel
                              {
                                  Prop1 = c1.Prop1,
                                  Prop2 = c1.Prop2,
                                  Prop3 = c1.Prop3,
                                  Prop4 = c1.Prop4,
                                  SerialNumber = c1.SerialNo,
                                  Prop5 = c2.Prop5,
                                  Prop6 = c2.Prop6
                              };

        var result = filteredResult.ToDataSourceResult(request);  
        // filteredResult is IQueryable of around 3 million records
        // filtering these on basis of request.Sorts and request.Filter will give 100 records
        // But I receive TimeOut exception here

        try
        {
            var serializer = new JavaScriptSerializer { MaxJsonLength = int.MaxValue };
            var jsonResult = new ContentResult
            {
                Content = serializer.Serialize(result),
                ContentType = "application/json"
            };

            return jsonResult;
        }
        catch (Exception ex)
        {
            ExceptionService.LogException(ex);
        }
    }

我的过滤结果包含 300 万条记录,在调用 ToDataSourceResult() 时会出现超时异常。此外,如果我尝试使用filteredResult.ToList() => 这会给我MemoryException。我无法删除超时异常。Kendo 说如果我们将 IQueryable 传递给 ToDataSourceResult,它将处理所有过滤,但在我的情况下它会给出异常。

我尝试通过处理所有 request.Sorts 和 Filters 来创建自己的 ToDataSourceResult() 替代方案,并使用仅传递页面大小记录

this.ObjectSet.Where(whereCondition).OrderBy("it." + sortBy).Skip(pageSize * (pageNumber - 1)).Take(pageSize);

但是这样我就无法处理过滤器的所有情况,并使这个方法对我项目中的所有网格都是通用的。

标签: kendo-gridtimeoutexception

解决方案


推荐阅读