JQuery DataTables服务器端分页

dav*_*ooh 7 c# asp.net jquery pagination jquery-datatables

在我的web-app中,我使用JQuery DataTables插件来显示从数据库中检索的数据.

我目前正在使用客户端分页,但我的表中的数据正在增长很多,并且在ASP.NET页面中加载现在变得有点慢.所以我打算切换到服务器端分页.

我知道DataTables插件支持它,但搜索我没有发现没有明确实现它.

我的主要疑问是:如果我在服务器端实现分页,我还必须实现排序,或者我可以将它委托给客户端?

你有没有经历过这个?

注意我使用Linq to SQL连接到我的数据库

Gon*_*ing 9

现有的答案可能适用于旧版本的dataTable,但当前版本(我使用的是1.10+)会传递开始记录和长度,因此任何建议pageNo * pageSize都会给出不正确的结果.

第一个简单的"手动"方法

接受的答案对于我想要的事情来说也非常复杂,经过一些调试后,我发现页面大小和开始记录只是作为Request名为start和的Http 值传递length.文本搜索将作为search[value]排序顺序传递给已命名的成员order[0][column]和排序方向order[0][dir]等.

我用来排序和过滤的基本代码如下所示:

从HTTP Request对象获取分页,排序和过滤值:

int startRec = 0;
int.TryParse(Request["start"], out startRec);
int pageSize = 10;
int.TryParse(Request["length"], out pageSize);
var search = Request["search[value]"];
var order = Request["order[0][column]"];
var direction = Request["order[0][dir]"];

var query = this._dataStore.Records.AsQueryable();
Run Code Online (Sandbox Code Playgroud)

首先应用(不区分大小写)搜索:

if (!string.IsNullOrWhiteSpace(search))
{
    query = query.Where(x => x.Label.ToLower().Contains(search.ToLower()));
}
Run Code Online (Sandbox Code Playgroud)

然后应用任何排序:

switch (order)
{
    // My id column
    case "0":
        query = (direction == "desc") ? query.OrderByDescending(x => x.Id) : query.OrderBy(x => x.Id);
        break;
    // My label column
    case "1":
        query = (direction == "desc") ? query.OrderByDescending(x => x.Label) : query.OrderBy(x => x.Label);
        break;
}
Run Code Online (Sandbox Code Playgroud)

最后应用分页:

query = query.Skip(startRec).Take(pageSize);
Run Code Online (Sandbox Code Playgroud)

正确的记录现在可以返回了.

更新(使用"Datatables.net for MVC5")

一旦我理解了服务器端dataTable的基础知识,就该开始寻找现有的插件/工具来简化这段代码了.到目前为止,对于MVC 5,我发现的最合适的是用于MVC5 nuget包的Datatables.net.

  1. 安装NuGet包

  2. 更改控制器操作以使用a DataTablesBinder来提供IDataTablesRequest接口

例如

 public JsonResult Table([ModelBinder(typeof(DataTablesBinder))] IDataTablesRequest requestmodel)
Run Code Online (Sandbox Code Playgroud)
  1. 首先应用任何搜索过滤器:

例如

if (!string.IsNullOrEmpty(requestmodel.Search.Value))
{
    query = query.Where(x => x.CompanyTypeName.Contains(requestmodel.Search.Value) || x.CompanyTypeDescription.Contains(requestmodel.Search.Value));
}
Run Code Online (Sandbox Code Playgroud)
  1. 应用任何排序:

例如

foreach (var sort in requestmodel.Columns.GetSortedColumns())
{
    switch (sort.Name)
    {
        case "CompanyTypeDescription":
            query = sort.SortDirection == Column.OrderDirection.Ascendant ? query.OrderBy(x => x.CompanyTypeDescription) : query.OrderByDescending(x => x.CompanyTypeDescription);
            break;
        case "CompanyTypeName":
        default:
            query = sort.SortDirection == Column.OrderDirection.Ascendant ? query.OrderBy(x => x.CompanyTypeName) : query.OrderByDescending(x => x.CompanyTypeName);
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 然后使用SkipTake以前一样应用分页:

例如

var result = query.Skip(requestmodel.Start).Take(requestmodel.Length).Select(x => new { x.CompanyTypeName, x.CompanyTypeDescription });
Run Code Online (Sandbox Code Playgroud)
  1. 最后使用DataTablesResponse对象返回JSON结果:

例如

return Json(new DataTablesResponse(requestmodel.Draw, result, query.Count(), base.RefSureContext.CompanyType.Count()), JsonRequestBehavior.AllowGet);
Run Code Online (Sandbox Code Playgroud)

这简化了所有搜索,排序和分页,使其成为一种易于重复的模式.

addin文档在这里.


Jup*_*aol 3

由于您使用的是 LINQ to SQL,分页非常简单:

var c = new MyDataContext("your string");

c.Employees.Skip(pageIndex * pageSize).Take(pageSize);
Run Code Online (Sandbox Code Playgroud)

此代码将在服务器上有效地分页

我没有使用DataTables jQuery 插件,但我假设您使用 AJAX 来获取数据(因为您没有使用 MVC),因此只需将当前页面索引以及每页行数作为参数发送 - page尺寸,仅此而已

为了满足要求,您还需要在服务器上对查询进行排序,因此您需要将排序条件发送到服务器并应用该订单。

要基于 a 在服务器上订购string,请检查以下问题:

IEnumerable<T> 上的动态 LINQ OrderBy

  • jQuery `dataTable` 自动发送*起始记录*和页面大小,而不是*页码*。排序作为索引列名称/值的集合发送。这个答案对于“dataTable”的使用具有误导性,并且仅适用于实现简单的手动分页/排序的情况。 (2认同)