zoukankan      html  css  js  c++  java
  • [翻译][MVC 5 + EF 6] 3:排序、过滤、分页

    原文:Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application

    1.添加排序

    1.1.修改ControllersStudentController.cs的Index:

    public ActionResult Index(string sortOrder)
    {
       ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
       ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
       var students = from s in db.Students
                      select s;
       switch (sortOrder)
       {
          case "name_desc":
             students = students.OrderByDescending(s => s.LastName);
             break;
          case "Date":
             students = students.OrderBy(s => s.EnrollmentDate);
             break;
          case "date_desc":
             students = students.OrderByDescending(s => s.EnrollmentDate);
             break;
          default:
             students = students.OrderBy(s => s.LastName);
             break;
       }
       return View(students.ToList());
    }

    1.2.修改ViewsStudentIndex.cshtml

    <p>
        @Html.ActionLink("Create New", "Create")
    </p>
    <table>
        <tr>
            <th>
                @Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm })
            </th>
            <th>First Name
            </th>
            <th>
                @Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm })
            </th>
            <th></th>
        </tr>

      效果图:

    Students_Index_page_with_sort_hyperlinks

    2.添加搜索框

    2.1.修改ControllersStudentController.cs的Index:

            public ViewResult Index(string sortOrder, string searchString)
            {
                ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
                ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
                var students = from s in db.Students
                               select s;
                if (!String.IsNullOrEmpty(searchString))
                {
                    students = students.Where(s => s.LastName.Contains(searchString)
                                           || s.FirstMidName.Contains(searchString));
                }
    switch (sortOrder)
                {
                    case "name_desc":
                        students = students.OrderByDescending(s => s.LastName);
                        break;
                    case "Date":
                        students = students.OrderBy(s => s.EnrollmentDate);
                        break;
                    case "date_desc":
                        students = students.OrderByDescending(s => s.EnrollmentDate);
                        break;
                    default:
                        students = students.OrderBy(s => s.LastName);
                        break;
                }
    
                return View(students.ToList());
            }

      在大多数情况下,我们调用同一个方法时,在EF实体集和内存中集合的扩展方法返回的结果是一样的;但是在一些情况下返回结果会不一样。

      例如当传递一个空的字符串时.NET Framework的Contains方法返回所有行,但是SQL Server Compact 4.0的EF 提供者(provider)的Contains返回0行。因此上面的代码中把Where语句放在if语句中,以保证对所有的SQL Server版本返回相同的数据。同样,.NET Framework的Contains方法默认是区分大小写的,因此,使用ToUpper方法将字符串显示转换为大写以确保以后代码改为仓储时(返回类型由IQueryable类型变成IEnumerable类型)返回结果不会发生变化(当调用Contains方法返回IEnumerable集合时,调用的是.NET Framework实现;返回IQueryable对象时,调用的是数据库提供者的实现)。

      当我们返回IQueryable对象时,不同的数据库提供者对空值的处理也不同。例如,在有些脚本中where条件中的table.Column != 0可能不会返回空值列。

    2.2.为ViewsStudentIndex.cshtml添加搜索框:

    <p>
        @Html.ActionLink("Create New", "Create")
    </p>
    @using (Html.BeginForm())
    {
        <p>
            Find by name: @Html.TextBox("SearchString")
            <input type="submit" value="Search" />
        </p>
    }

      效果图:

    Students_Index_page_with_search_box

    3.添加分页

    3.1.安装PagedList.MVC:

    Install-Package PagedList.Mvc

    3.2.修改ControllersStudentController.cs

    using PagedList;
    public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
    {
       ViewBag.CurrentSort = sortOrder;
       ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
       ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
      
       if (searchString != null)
       {
          page = 1;
       }
       else
       {
          searchString = currentFilter;
       }
    
       ViewBag.CurrentFilter = searchString;
    
    var students = from s in db.Students
                      select s;
       if (!String.IsNullOrEmpty(searchString))
       {
          students = students.Where(s => s.LastName.Contains(searchString)
                                 || s.FirstMidName.Contains(searchString));
       }
       switch (sortOrder)
       {
          case "name_desc":
             students = students.OrderByDescending(s => s.LastName);
             break;
          case "Date":
             students = students.OrderBy(s => s.EnrollmentDate);
             break;
          case "date_desc":
             students = students.OrderByDescending(s => s.EnrollmentDate);
             break;
          default:  // Name ascending 
             students = students.OrderBy(s => s.LastName);
             break;
       }
    
       int pageSize = 3;
       int pageNumber = (page ?? 1);
       return View(students.ToPagedList(pageNumber, pageSize));
    }

      当页面第一次加载或者用户没有点击分页或排序链接时,所有的参数都是空值。

      ViewBag.CurrentSort用于点击分页时保存排序信息。

      ViewBag.CurrentFilter用于保存搜索信息,并且当页面刷新时给搜索框赋值。当搜索条件改变时,page值重置为1。

    3.3.修改ViewsStudentIndex.cshtml

    @model PagedList.IPagedList<ContosoUniversity.Models.Student>
    @using PagedList.Mvc;
    <link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
    
    @{
        ViewBag.Title = "Students";
    }
    
    <h2>Students</h2>
    
    <p>
        @Html.ActionLink("Create New", "Create")
    </p>
    @using (Html.BeginForm("Index", "Student", FormMethod.Get))
    {
        <p>
            Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
            <input type="submit" value="Search" />
        </p>
    }
    <table class="table">
        <tr>
            <th>
                @Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm, currentFilter=ViewBag.CurrentFilter })
            </th>
            <th>
                First Name
            </th>
            <th>
                @Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm, currentFilter=ViewBag.CurrentFilter })
            </th>
            <th></th>
        </tr>
    
    
    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.LastName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.FirstMidName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.EnrollmentDate)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
                @Html.ActionLink("Details", "Details", new { id=item.ID }) |
                @Html.ActionLink("Delete", "Delete", new { id=item.ID })
            </td>
        </tr>
    }
    
    </table>
    <br />
    Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
    
    @Html.PagedListPager(Model, page => Url.Action("Index", 
        new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))

      BeginForm提交form数据的默认方式是post,post方式是通过HTTP消息体而不是通过URL查询字符串传递参数。我们通过FormMethod.Get把它指定为HTTP GET,这样用户就可以将URL收藏为书签。当动作不会导致更新时W3C HTTP GET使用指南推荐我们使用GET。

      效果图:

    Students_index_page_with_paging

    4.添加About页面展示Student统计信息

    4.1.创建视图模型:

      新建ViewModels文件夹EnrollmentDateGroup.cs

        public class EnrollmentDateGroup
        {
            [DataType(DataType.Date)]
            public DateTime? EnrollmentDate { get; set; }
    
            public int StudentCount { get; set; }
        }

    4.2.修改HomeController.cs

    private SchoolContext db = new SchoolContext();
    //...
    public ActionResult About()
    {
        IQueryable<EnrollmentDateGroup> data = from student in db.Students
                   group student by student.EnrollmentDate into dateGroup
                   select new EnrollmentDateGroup()
                   {
                       EnrollmentDate = dateGroup.Key,
                       StudentCount = dateGroup.Count()
                   };
        return View(data.ToList());
    }
    //...
    protected override void Dispose(bool disposing)
    {
        db.Dispose();
        base.Dispose(disposing);
    }

    4.3.修改ViewsHomeAbout.cshtml

    @model IEnumerable<ContosoUniversity.ViewModels.EnrollmentDateGroup>
               
    @{
        ViewBag.Title = "Student Body Statistics";
    }
    
    <h2>Student Body Statistics</h2>
    
    <table>
        <tr>
            <th>
                Enrollment Date
            </th>
            <th>
                Students
            </th>
        </tr>
    
    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.EnrollmentDate)
            </td>
            <td>
                @item.StudentCount
            </td>
        </tr>
    }
    </table>

      效果图:

    About_page

  • 相关阅读:
    UI层复习笔记
    async 的三大返回类型
    用scikit-learn进行LDA降维
    关于解决python线上问题的几种有效技术
    ASP.NET Core MVC/WebAPi 模型绑定探索
    浅谈 Fragment 生命周期
    vue2.0实践的一些细节
    Linux----------Mysql死锁
    Linux----------容器docker file
    Linux----------常用容器命令
  • 原文地址:https://www.cnblogs.com/walden1024/p/4578885.html
Copyright © 2011-2022 走看看