我正在使用Asp net 5,NHibernate 3.3和Kendo UI MVC包装器进行网格渲染,以呈现客户订单表。数据库中已经有很多订单,并且数量在不断增长。因此,我决定使用服务器端分页以避免从数据库中获取所有订单。据我所知,您无法手动进行分页,也无法将筛选,排序和分组委托(delegate)给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();
我将很高兴就如何在此处添加分组提供任何建议。
最佳答案
我花了几个月的时间来弄清楚使用Kendo数据源和Kendo Grid进行服务器端分组的情况。分页,排序和过滤非常简单。但是无论出于何种原因,Telerik都没有为诸如分组之类的关键LOB流程提供足够的支持文档。很高兴您发布此问题,以便有机会分享我的代码。
解决方案
基本上,解决方案归结为了解两个关键部分,可以在以下示例项目中查看它们:https://www.dropbox.com/s/ygtk8rwl1hwjvth/KendoServerGrouping.zip?dl=0
您要下载的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来配置Kendo DataSource,而不是MVC包装器。不过,我最近在Telerik的文档中显示了found a link,该文档显示了Razor / ASPX中的MVC包装器声明。
服务器魔术
基本上, Magic 的第一部分是以下服务器端代码,它们位于kent_strong KendoServerGrouping.Web \ Controllers 目录中的示例WebApi Controller 中:
[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的数据源(我已经测试了Entity Framework和Telerik数据访问/开放访问)。我还能够使用MongoDB C#驱动程序对MongoDB集合进行分组。但是,只是作为概念证明,尚未经过性能的测试。
出于本示例的目的,WebAPI Controller 中有静态数据源来伪造IQueryable集合。自然地,当您交换了自己的数据源时,您可以从第45-57行删除静态数据。
客户端魔术
Kendo DataSource会自动从网格中传递一个专门的DataSourceRequest对象,该对象包含用于服务器端分页,过滤,排序和分组的所有参数,所提供的可以将DataSource模式包装在以下JavaScript中:
schema: $.extend(true, {}, kendo.data.schemas["aspnetmvc-ajax"], {
});
这也许是我所追踪的最难捉摸的代码行。 在几个月的时间里,与Telerik进行了大约十二次交流,以使他们咳嗽起来。即使在那时,它也完全是偶然地被揭露了。为什么在他们的文档中没有这么重要的细微差别已经超出了我的范围。
仔细检查
index.html
文件下半部分的每个Kendo DataSource配置设置。最重要的是,请注意不存在的内容,例如batch
和mvcTransport
选项。包括后一个选项将以某种方式否定上述“aspnetmvc-ajax” 模式属性。在数据源的 parmaterMap 函数中,请注意,当(且仅当)执行读取操作时,必须存在以下行:
return mvcTransport.parameterMap(options, operation);
您还需要确保在执行DataSource之前将其包含在HTML中:
<script src="//cdn.kendostatic.com/[Version]/js/kendo.aspnetmvc.min.js"></script>
最终结果
运行 KendoServerGrouping.Web 项目( index.html ),如果一切顺利,将用5个记录填充网格,这些记录包含 AccountId , AccountName , AccountType Code ,字段。如果您将可见网格行的数量设置为 2 并按 AccountTypeCode 或 CreatedOn 分组,则会看到该分组遍历分页,我相信这是您要寻找的最终结果。
我希望该示例项目能够正常工作,并且适合您的情况。如果您有任何疑问,请告诉我,我们将尽力为您提供帮助。
附言这是我的第一篇SO文章,因此,如果某些内容不符合SO标准,请对我轻松一点。祝好运!
关于nhibernate - Kendo网格服务器端分组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23649952/