C# MVC2 Jqgrid - 进行服务器端分页的正确方法是什么?

发布于 2024-10-02 10:29:18 字数 2980 浏览 0 评论 0原文

我有一个 jqgrid,其中数据库表有几千行,但 jqrid 一次只显示 15 行。

它应该显示得非常快(查询 15 行并不需要很长时间)。但它需要 10 - 20 秒,这表明它每次都检索整个表。

网格定义如下:

$("#Products").jqGrid({
url: url, mtype: "get", datatype: "json", jsonReader: {
    root: "Rows", page: "Page", total: "Total", records: "Records", repeatitems: false,
    userdata: "UserData",id: "Id"},
colNames: ["Product Id","Product Code", ... etc ],
colModel: [{ name: "Id", ... etc}],
viewrecords: true, height: 400, width: 800, pager: $("#jqgPager"),
rowNum: 15, rowList: [50, 100, 200], 
autowidth: true, multiselect: false

服务器端(MVC2 操作)执行此操作:

var model = (from p in products
    select new
    {
    p.Id, p.ProductCode, p.ProductDescription,
    AllocatedQty = p.WarehouseProducts.Sum(wp => wp.AllocatedQuantity),
    QtyOnHand = p.WarehouseProducts.Sum(wp => wp.OnHandQuantity)
    }).AsQueryable();

    JsonResult json = Json(model.ToGridData(
        page, rows, orderBy, "", 
        new[] { "Id", "ProductCode", "ProductDescription", "AllocatedQty", "QtyOnHand" }),
            JsonRequestBehavior.AllowGet);

最后 model.ToGridData 扩展方法执行此操作:

var data =_service.GetAll(); 
var page = data.Skip((index) * pageSize).Take(pageSize);
list.Add(page.AsEnumerable);

我对问题所在有点迷失:

  • 我是否设置了 jqgrid 分页选项错误地?
  • 我是否写了糟糕的 Linq,无论如何都会提取所有行? 例如 Sum() 是否会导致读取所有行?
  • 我是否错误地执行了 .Skip().Take() ?
  • 我完全错过了其他东西吗?

编辑

当将我的代码与 Oleg 发布的示例进行比较时,我可以看到我按以下顺序执行操作:

  1. getAll
  2. select model fields
  3. page

而 Olegs 示例似乎按此顺序:

  1. getAll
  2. page
  3. select model fields

所以我已经更改为这么多更简单的实现:

public ActionResult GetProductList(int page, int rows, string sidx, string sord, 
string searchOper, string searchField, string searchString)
{
        List<Product> products = _productService.GetAllProducts();
        int totalRecords = products.Count();

        var pagedData = products.Skip((page > 0 ? page - 1 : 0) * rows).Take(rows);

        var model = (from p in pagedData
                    select new
                    {
                        p.Id, p.ProductCode, p.ProductDescription,
                        Barcode = string.Empty, UnitOfMeasure = string.Empty,
                        p.PackSize, AllocatedQty = string.Empty,
                        QtyOnHand = string.Empty }).ToList();

        var jsonData = new
        {
            total = page, records = totalRecords,
            page = (totalRecords + rows - 1) / rows, rows = model
        };

        return Json(jsonData, JsonRequestBehavior.AllowGet);
}

然而,这有一个新问题:

A circular reference was detected while serializing an object of type
'System.Data.Entity.DynamicProxies.Product_FA935D3899E2...

我现在可以看到 Oleg 示例的唯一区别是他的 getAll 返回 IQueryable,而我的只是 List

I have a jqgrid where the database table has a few thousand rows, but the jqrid shows only 15 at a time.

It should be displaying very quickly (it doesnt take long to query 15 rows). But instead it takes 10 - 20 seconds, which indicates to that it is retrieving the entire table each time.

The grid is defined like this:

$("#Products").jqGrid({
url: url, mtype: "get", datatype: "json", jsonReader: {
    root: "Rows", page: "Page", total: "Total", records: "Records", repeatitems: false,
    userdata: "UserData",id: "Id"},
colNames: ["Product Id","Product Code", ... etc ],
colModel: [{ name: "Id", ... etc}],
viewrecords: true, height: 400, width: 800, pager: $("#jqgPager"),
rowNum: 15, rowList: [50, 100, 200], 
autowidth: true, multiselect: false

And the server side (MVC2 action) does this:

var model = (from p in products
    select new
    {
    p.Id, p.ProductCode, p.ProductDescription,
    AllocatedQty = p.WarehouseProducts.Sum(wp => wp.AllocatedQuantity),
    QtyOnHand = p.WarehouseProducts.Sum(wp => wp.OnHandQuantity)
    }).AsQueryable();

    JsonResult json = Json(model.ToGridData(
        page, rows, orderBy, "", 
        new[] { "Id", "ProductCode", "ProductDescription", "AllocatedQty", "QtyOnHand" }),
            JsonRequestBehavior.AllowGet);

And finally the model.ToGridData extension method does this:

var data =_service.GetAll(); 
var page = data.Skip((index) * pageSize).Take(pageSize);
list.Add(page.AsEnumerable);

And I'm a bit lost as to where the problem lies:

  • Have I set the jqgrid paging options incorrectly?
  • Have I written bad Linq that pulls all rows regardless?
    eg does the Sum() cause all rows to be read?
  • Have I done the .Skip().Take() incorrectly?
  • Have I missed something else entirely?

EDIT

When comparing my code to the example posted by Oleg I can see that I do things in this order:

  1. getAll
  2. select model fields
  3. page

Wheras Olegs sample seems to be in this order:

  1. getAll
  2. page
  3. select model fields

So I've changed to this much simpler implementation:

public ActionResult GetProductList(int page, int rows, string sidx, string sord, 
string searchOper, string searchField, string searchString)
{
        List<Product> products = _productService.GetAllProducts();
        int totalRecords = products.Count();

        var pagedData = products.Skip((page > 0 ? page - 1 : 0) * rows).Take(rows);

        var model = (from p in pagedData
                    select new
                    {
                        p.Id, p.ProductCode, p.ProductDescription,
                        Barcode = string.Empty, UnitOfMeasure = string.Empty,
                        p.PackSize, AllocatedQty = string.Empty,
                        QtyOnHand = string.Empty }).ToList();

        var jsonData = new
        {
            total = page, records = totalRecords,
            page = (totalRecords + rows - 1) / rows, rows = model
        };

        return Json(jsonData, JsonRequestBehavior.AllowGet);
}

However this has a new problem:

A circular reference was detected while serializing an object of type
'System.Data.Entity.DynamicProxies.Product_FA935D3899E2...

The only difference I can see now with Oleg's sample is that his getAll returns IQueryable where mine is just List.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

提赋 2024-10-09 10:29:18

您应该发布更完整的代码。例如,当前代码中未定义 model.ToGridData 。如何从输入参数等计算index也不清楚。只有model.ToGridData()可以判断你的程序产生的输出是否对应于你定义的jsonReader

我建议您查看 这个旧答案,其中同时使用了分页和排序。在另一个答案中,您会发现更多代码示例的参考。

You should post more full code. The model.ToGridData is not defined in the current code for example. How you caclulate index from the imput patrameters and so on are also unclear. Only having model.ToGridData() one can say whether the output which your program produce are correspond to the jsonReader which you define.

I recommend you to look this old answer, where both paging and sorting are used. In one more answer you will find more references to code examples.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文