【问题标题】:Kendo grid server side grouping剑道网格服务器端分组
【发布时间】:2023-03-16 16:32:01
【问题描述】:

我正在使用 Asp net 5、NHibernate 3.3 和 Kendo UI MVC 包装器用于网格来呈现客户订单表。数据库中已经有很多订单,而且数量还在不断增长。所以我决定使用服务器端分页来避免从数据库中获取所有订单。据我所知,您不能手动进行分页并将过滤、排序和分组委托给 ToDataSourceResult 方法。要么全有,要么全无。因此我尝试实现所谓的'custom binding'。在我开始分组之前没问题。我需要先分组,然后在组内排序,然后提取特定页面的数据以及所有这些,而不将所有数据加载到内存中。我的代码是这样的(为了简化阅读,我把它们放在一起):

var orderList = CurrentSession.QueryOver<Order>();

// Filtering. Filter is a search string obtained from DataSourceRequest
var disjunction = new Disjunction();
disjunction.Add(Restrictions.On<Order>(e => e.Number).IsLike("%" + filter + "%"));
disjunction.Add(Restrictions.On<Order>(e => e.Customer).IsLike("%" + filter + "%"));
orderList = orderList.Where(disjunction);

// Sorting. sortColumn is also from DataSourceRequest
switch (sortColumn)
{
        case "Number":
            orderList = orderList.OrderBy(x => x.Number).Desc;
            break;
        case "GeneralInfo.LastChangeDate":
            orderList = orderList.OrderBy(x => x.LastChangeDate).Desc;
            break;
        default:
            orderList = orderList.OrderBy(x => x.Number).Desc;
            break;
     }
}

// Total is required for kendo grid when you do paging manually
var total = orderList.RowCount();


var orders = orderList
    .Fetch(x => x.OrderGoods).Eager
    .Fetch(x => x.OrderComments).Eager
    .Fetch(x => x.Documents).Eager
    .Fetch(x => x.Partner).Eager
    .Skip((request.Page - 1)*request.PageSize).Take(request.PageSize).List();

我很乐意就如何在此处添加分组提供任何建议。

【问题讨论】:

    标签: nhibernate kendo-grid grouping queryover


    【解决方案1】:

    我花了几个月的时间来计算使用 Kendo DataSource 和 Kendo Grid 的服务器端分组。分页、排序和过滤相当容易。但无论出于何种原因,Telerik 都没有为分组这样的关键 LOB 流程提供足够的支持文档。很高兴您发布了这个问题,以便我有机会分享我的代码。

    解决方案

    基本上,解决方案归结为了解 2 个关键部分,可以在以下示例项目中查看它们:https://www.dropbox.com/s/ygtk8rwl1hwjvth/KendoServerGrouping.zip?dl=0

    您正在下载的 Visual Studio (2012 | 2013) 解决方案中有一个 Web 应用程序项目,其中包含对 Kendo.Mvc 库的引用。您可以从 Telerik 的控制面板安装程序下载最新的 UI for ASP.NET 二进制文件。安装后二进制文件将位于以下 Windows 目录中:C:\Program Files (x86)\Telerik\UI for ASP.NET MVC [Telerik Release Version]\wrappers\aspnetmvc\Binaries\ [您的 MVC 版本]\Kendo.Mvc.dll.

    注意:我的解决方案使用 Telerik 的 MVC 传输机制,它提供了成熟的服务器端分页、过滤、排序以及最显着的分组。 但是,我使用纯 JavaScript 来配置 Kendo DataSource 而不是 MVC 包装器。不过,我最近在 Telerik 的文档中found a link 显示了 Razor/ASPX 中的 MVC 包装器声明。

    服务器魔法

    基本上,magic 的第一部分是以下服务器端代码,位于 KendoServerGrouping.Web\Controllers 中的示例 WebApi 控制器中strong> 目录:

        [System.Web.Http.AcceptVerbs("GET", "ASPNETMVC-AJAX")]
        public Kendo.Mvc.UI.DataSourceResult GetAllAccounts([System.Web.Http.ModelBinding.ModelBinder(typeof(WebApiDataSourceRequestModelBinder))] Kendo.Mvc.UI.DataSourceRequest request)
        {
            var kendoRequest = new Kendo.Mvc.UI.DataSourceRequest
            {
                Page = request.Page,
                PageSize = request.PageSize,
                Filters = request.Filters,
                Sorts = request.Sorts,
                Groups = request.Groups,
                Aggregates = request.Aggregates
            };
    
            // Set this to your ORM or other data source
            IQueryable accounts = dbContext.Accounts;
    
            /*
               The data source can even be a MongoDB collection using the
               .AsQueryable() extension and the MongoDB C# driver
    
               var accounts = collection.FindAllAs<Account>().AsQueryable();
            */
    
            var data = accounts.ToDataSourceResult(kendoRequest);
    
            var result = new DataSourceResult()
            {
                AggregateResults = data.AggregateResults,
                Data = data.Data,
                Errors = data.Errors,
                Total = data.Total
            };
    
            return result;
        }
    

    这就是当用户与之交互时网格将自动处理的四个服务器端操作中的任何一个所需要的全部内容。特别注意方法上方的AcceptVerbs属性;它必须包含 “ASPNETMVC-AJAX” 属性,DataSourceRequest 输入参数才能正常工作。 ToDataSourceResult() 是最新版本的 Kendo.Mvc.dll 库提供的扩展,我之前指出过。

    上面的代码(据我所知)适用于任何 IQueryable 数据源,例如来自 ORM 的那些(我已经测试了实体框架和 Telerik 数据访问/开放访问)。我还能够使用 MongoDB C# 驱动程序对 MongoDB 集合进行分组。但是,这只是概念验证,尚未经过性能测试

    就本示例而言,WebAPI 控制器中有静态数据源来伪造 IQueryable 集合。当然,您可以在换入自己的数据源后删除第 45-57 行的静态数据

    客户魔法

    Kendo DataSource 自动从网格传入一个专门的 DataSourceRequest 对象,该对象包含服务器端分页、过滤、排序和分组的所有参数,提供你包装你的以下 JavaScript 中的 DataSource 架构:

    schema: $.extend(true, {}, kendo.data.schemas["aspnetmvc-ajax"], {
    });
    

    这可能是我追踪到的最难以捉摸的一行代码。 在几个月的时间里,与 Telerik 进行了十几次交流,才让他们把它弄出来。即便如此,它被揭露也纯属偶然。为什么他们的文档中没有如此重要的细微差别,我无法理解。

    仔细查看index.html 文件下半部分的每个 Kendo DataSource 配置设置。最重要的是,请注意不存在的内容,例如 batchmvcTransport 选项。包含后一个选项会以某种方式否定上述 “aspnetmvc-ajax” 架构属性。

    在 DataSource 的 parmaterMap 函数中,请注意,当且仅当 - 执行读取操作时,必须存在以下行:

    return mvcTransport.parameterMap(options, operation);
    

    您还需要确保在数据源执行之前将其包含在您的 HTML 中:

    <script src="//cdn.kendostatic.com/[Version]/js/kendo.aspnetmvc.min.js"></script>
    

    最终结果

    运行 KendoServerGrouping.Web 项目 (index.html),如果一切顺利,网格将填充 5 条包含 AccountId 的记录strong>、AccountNameAccountTypeCodeCreatedOn 字段。如果将可见网格行数设置为 2 并按 AccountTypeCodeCreatedOn 分组,您会看到分组遍历分页,我相信这是您正在寻找的最终结果。

    我希望示例项目能够正常工作并且非常适合您的情况。如果您有任何问题,请告诉我,我会尽力提供帮助。

    附:这是我在 SO 上的第一篇文章,所以如果某些内容不符合 SO 标准,请对我放轻松。祝你好运!

    【讨论】:

    • 非常感谢您提供如此详细的回答!您提供的示例项目工作得很好,它演示了我需要的行为。这将是一个很好的起点。顺便说一句,我很惊讶地看到解决方案如此棘手。 Telerik 在这里肯定有一些改进的空间。
    • 我很高兴它成功了!我完全同意解决方案很棘手;执行服务器端分组不应该这么难。祝你好运!
    • 不用Telerik的DataSourceRequest,也可以试试KendoGridBinderEx
    • @Stef 谢谢你的建议。其实我前段时间就遇到过这个包,虽然不是很受欢迎,所以我没有太注意它。我想我会给它一个更好的外观。
    • @vsevolod,这个包有两个版本,原来的 KendoGridBinder 和我的更新版本 KendoGridBinderEx
    【解决方案2】:

    我想用this jewel I found on Telerik's forums 补充@aaron-jessen 答案:

    $("#grid").kendoGrid({
      dataSource: {
        type: "aspnetmvc-ajax",  // If missing may cause NULL values in ApiController
      }
    })
    

    【讨论】:

    • 使用 type: "aspnetmvc-ajax" 意味着 Kendo UI Grid 将忽略 parameterMap: function() {...}。而是使用dataSource.transport.read.data: function(e) {...}
    猜你喜欢
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 2019-06-28
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多