【问题标题】:Paging on the database server with Telerik MVC Extensions Grid使用 Telerik MVC Extensions Grid 在数据库服务器上进行分页
【发布时间】:2011-10-17 12:48:58
【问题描述】:

Telerik mention 这个功能:

基于 Linq 的表达式引擎,用于将网格操作(分页、排序、过滤和分组)推送到数据库服务器

但是如何启用它呢?这些例子都取了 IEnumerable 的东西。

【问题讨论】:

    标签: asp.net-mvc telerik


    【解决方案1】:

    这在一定程度上取决于您将数据发送到视图的方式。如果将 linq 查询保留为惰性评估,那么您将在数据库上进行分页。但是,如果在您的数据层中执行 ToList() 或其他枚举,您将错过这一点,拉取所有数据,并且必须设置一些东西来手动分页。

    为了更好地展示...

    // In your initial page load
    public ActionResult Index()
    {
        return View(new MyViewModel
        {
            // ... other view data
    
            // set order or .Where for initial load, but don't use .ToList or enumerate
            MyObjects = _db.MyObjects.OrderBy(m => m.Name)
            // When this is passed into the grid, it will finalize the paging there
            // and when the grid enumerates MyObjects, it will only pull the relevant
            // items from the database.
        });
    }
    

    如果您使用的是 ajax 绑定...

    // In an ajax grid responder action
    [GridAction]
    public ActionResult AjaxGridAction()
    {
        // Assuming _db is a CodeFirst DbContext, GridModel will handle filtering,
        // paging, and sorting in the database as linq applies those methods to the
        // IQueryable _db.MyObjects
        return View(new GridModel(_db.MyObjects));
    }
    

    如果您使用的是存储库模式(尽管 DbContext 确实已经是一个存储库),那么让它返回惰性对象:

    public IEnumerable<T> GetMyObjects()
    {
        // Don't use ToList or enumerate them in your repository - that will
        // pull all the data before the Telerik grid has filtered it.
        return _db.MyObjects;
    }
    

    即使所有内容都围绕 IEnumerable 进行,但当需要实际迭代集合时,具体类型(上述示例中的 DbSet)将是实际处理该集合的对象。

    如果您使用 AutoMapper 之类的工具,请注意在映射过程中很容易意外拉取所有记录。 AutoMapper 2 有一个解决方案,可以在不迭代的情况下从数据库中投影出来,但还没有文档。在我有时间进一步研究 AutoMapper 2 之前,我一直在使用 this solution for that

    _db.MyObjects.Project().To<MyObjectsViewModel>();
    

    基本上包装自动项目属性而不是这样做:

    _db.MyObjects
        .Select(o => new MyObjectsViewModel { // manually map properties, ewww });
    

    【讨论】:

    • 谢谢,所以我猜他们会检查 IEnumerable 是否是 IQueryable。解释它。干杯,皮特。
    • 他们真的不需要检查——这就是 Linq 的乐趣所在。具体的 IEnumerable 将是执行分页的那个。在 Telerik 代码中,他们只使用 .Skip(page).Take(pageSize)。具体实现者 DbSet 或其他一些 IQueryable 负责将其实际转换为 SQL。由于 Linq 是惰性求值的,在 .ToList 或其他 .To__ 之前,传递到网格的集合还没有被拉取并且可以在数据库中分页。无论具体类型是什么,Telerik 代码都会调用相同的代码,并且不需要做任何不同的事情。
    • 您将惰性求值与代码引用(表达式树)混淆了。例如,db.Customers.AsEnumerable().Take(10) 仍然会从数据库中获取所有客户。简单看一下源代码,Telerik 检查 IEnumerable 是否已经是 Telerik.Web.Mvc.Infrastructure.QueryableFactory 中的 IQueryable。
    【解决方案2】:

    对于服务器分页/排序,您应该设置 GridOperationMode.Server 属性。

    有一个使用示例:

    Html.Telerik().Grid<PartnerUserViewModel>()
        .Name("Grid").DataBinding(binding =>    binding.Ajax().OperationMode(GridOperationMode.Server).Select("GetUsers", "Partner")).Columns(columns =>
        {
            columns.Bound(o => o.Representer).Title("Representer");  
        });          
        .Sortable(sorting => sorting.OrderBy(sortOrder => sortOrder.Add(p => p.DateCreated).Descending()))
        .Filterable()
        .Pageable(pager => pager.Position(GridPagerPosition.Both).PageSize(5))
        .Groupable()
    

    【讨论】:

      猜你喜欢
      • 2011-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 2012-01-20
      • 1970-01-01
      • 2012-07-18
      相关资源
      最近更新 更多