Nhibernate 剑道网格服务器端分组

Nhibernate 剑道网格服务器端分组,nhibernate,kendo-grid,grouping,queryover,Nhibernate,Kendo Grid,Grouping,Queryover,我正在使用Asp net 5、NHibernate 3.3和Kendo UI MVC wrapper for grid来呈现客户订单表。数据库中已经有很多订单,而且数量还在不断增长。所以我决定使用服务器端分页来避免从数据库获取所有订单。据我所知,您不能手动分页,也不能将筛选、排序和分组委托给ToDataSourceResult方法。要么全有,要么什么都没有。因此,我试图实现所谓的。在我开始分组之前没问题。我需要先分组,然后在组内排序,然后提取特定页面的数据以及所有这些数据,而不将所有数据加载到内

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

var orderList=CurrentSession.QueryOver();
//过滤。筛选器是从DataSourceRequest获取的搜索字符串
var析取=新析取();
disjunction.Add(Restrictions.On(e=>e.Number).IsLike(“%”+filter+“%”));
disjunction.Add(Restrictions.On(e=>e.Customer).IsLike(“%”+filter+“%”));
orderList=orderList.Where(析取);
//分类。sortColumn也来自DataSourceRequest
开关(sortColumn)
{
案例“编号”:
orderList=orderList.OrderBy(x=>x.Number).Desc;
打破
案例“GeneralInfo.LastChangeDate”:
orderList=orderList.OrderBy(x=>x.LastChangeDate).Desc;
打破
违约:
orderList=orderList.OrderBy(x=>x.Number).Desc;
打破
}
}
//手动分页时,剑道网格需要总计
var total=orderList.RowCount();
var orders=orderList
.Fetch(x=>x.OrderGoods)
.Fetch(x=>x.OrderComments)
.Fetch(x=>x.Documents)。急切
.Fetch(x=>x.Partner)
.Skip((request.Page-1)*request.PageSize).Take(request.PageSize.List();

对于如何在这里添加分组,我很乐意提供任何建议。

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

解决方案

基本上,解决方案归结为了解两个关键部分,可以在以下示例项目中查看它们:

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

注意:我的解决方案使用Telerik的MVC传输机制,提供全面的服务器端分页、过滤、排序,最显著的是分组但是,我使用纯JavaScript来配置剑道数据源,而不是MVC包装器。尽管如此,我最近在Telerik的文档中看到了Razor/ASPX中的MVC包装声明

服务器魔法

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

    [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;
    }
这可能是我所追踪到的最难以捉摸的一行代码。几个月来,与Telerik进行了十几次交流,才让他们说出这一行代码。即使在那时,它还是被揭露出来,纯属偶然。我无法理解为什么他们的文档中没有如此关键的细微差别

仔细查看
index.html
文件下半部分的每个剑道数据源配置设置。最重要的是,请注意没有的内容,例如
批处理
mvcTransport
选项。包含后一个选项会以某种方式否定上面的“aspnetmvc ajax”模式属性

在数据源的parmaterMap函数中,请注意,当执行读取操作时,且仅当执行读取操作时,必须出现以下行:

return mvcTransport.parameterMap(options, operation);
在执行数据源之前,您还需要确保在HTML中包含以下内容:

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

最终结果

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

我希望样本项目的工作,是一个很好的适合你的情况。如果你有任何问题,请告诉我,我会尽力帮助你


另外,这是我第一次在SO上发表文章,所以如果有什么不符合SO标准,请对我宽容一些。祝你好运

我想在@aaron jessen的回答中添加以下内容:


非常感谢您如此详细的回答!您提供的示例项目工作得很好,它演示了我需要的行为。这将是一个极好的起点。顺便说一句,我很惊讶地看到这个解决方案如此棘手。Telerik在这里肯定有一些改进的空间。我很高兴它成功了!我完全同意解决方案是棘手的;执行服务器端分组不应该这么难。好的,我
return mvcTransport.parameterMap(options, operation);
<script src="//cdn.kendostatic.com/[Version]/js/kendo.aspnetmvc.min.js"></script>
$("#grid").kendoGrid({
  dataSource: {
    type: "aspnetmvc-ajax",  // If missing may cause NULL values in ApiController
  }
})