ASP.NET MVC:排序、搜索、分页以及多对多数据库

ASP.NET MVC自动生成的手脚架很方便,但是在我们实际的工作中,那仅仅是开始而已。下面我们以一个实例来讨论ASP.NET MVC的排序、搜索和分页,最后我们完成一个简单的多对多数据库。

打开VS2015,创建一个MVC项目,取名为PersonnelTask,新建一个Model-Personnels:

public class Personnels
    {
        public int PersonnelsId { get; set; }
        [Required(ErrorMessage = "请输入名称。")]
        [StringLength(160, MinimumLength = 4)]
        [Display(Name = "名称")]
        public string Name { get; set; }
        [Required(ErrorMessage = "请输入薪水。")]
        [Display(Name = "薪水")]
        public decimal Pay { get; set; }
        [Required(ErrorMessage = "请输入入职时间。")]
        [Display(Name = "入职时间")]
        public DateTime Date { get; set; }
    }

接着,我们新建一个控制器:包含视图的MVC 5控制器,具体设计如下图:

ASP.NET MVC:排序、搜索、分页以及多对多数据库_第1张图片
mark

完成手脚架后,我们开始填入种子数据

1.在项目里面的Models文件夹,新建一个种子类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace PersonnelTask.Models
{
    public class DbInitializer:System.Data.Entity.DropCreateDatabaseAlways
    {
        protected override void Seed(PersonnelTaskContext context)
        {
            context.Personnels.Add(new Personnels { Name = "张三", Pay = 2000, Date = DateTime.Now });
            context.Personnels.Add(new Personnels { Name = "李四", Pay = 2000, Date = DateTime.Now });
            context.Personnels.Add(new Personnels { Name = "张马子", Pay = 2000, Date = DateTime.Now });
            context.Personnels.Add(new Personnels { Name = "阳明", Pay = 2000, Date = DateTime.Now });
            context.Personnels.Add(new Personnels { Name = "张伟", Pay = 2000, Date = DateTime.Now });
            context.Personnels.Add(new Personnels { Name = "徐可", Pay = 2000, Date = DateTime.Now });
            context.Personnels.Add(new Personnels { Name = "王丽", Pay = 2000, Date = DateTime.Now });
            context.Personnels.Add(new Personnels { Name = "玛丽", Pay = 2000, Date = DateTime.Now });
            context.Personnels.Add(new Personnels { Name = "麦克", Pay = 2000, Date = DateTime.Now });
            context.Personnels.Add(new Personnels { Name = "潭门", Pay = 2000, Date = DateTime.Now });
            context.Personnels.Add(new Personnels { Name = "于谦", Pay = 2000, Date = DateTime.Now });
            context.Personnels.Add(new Personnels { Name = "郭德", Pay = 2000, Date = DateTime.Now });
            base.Seed(context);
        }
    }
}

2.打开Global.asax.cs,加入下面打代码:

 protected void Application_Start()
        {
            Database.SetInitializer(new DbInitializer());
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }

下面我们来演示一下排序。

数据库排序的功能是很重要的,在本例中,我希望可以通过点击“薪水”或者“入职时间”,重新按照“薪水”或者“入职时间”的升序或者降序来排列我们的数据。

思路:我们在index控制器里面增加一个参数sortOrder,用它来接收需要排序的值 public ActionResult Index(string sortOrder)

通过这些值的不同,我们的数据排序就是根据这些值进行排列的。下面是源代码:

public ActionResult Index(string sortOrder)
        {
            var ps = from s in db.Personnels select s;

            ViewBag.PaySortPam = sortOrder == "pay" ? "pay_desc" : "pay";
            ViewBag.DateSort = sortOrder == "date" ? "date_desc" : "date";
            switch (sortOrder)
            {
                case "pay_desc":
                    ps = ps.OrderByDescending(s => s.Pay);
                    break;
                case "pay":
                    ps=ps.OrderBy(s => s.Pay);
                    break;
                case "date_desc":
                    ps = ps.OrderByDescending(s => s.Date);
                    break;
                case "date":
                    ps=ps.OrderBy(s => s.Date);
                    break;
                default:
                    ps = ps.OrderByDescending(s => s.PersonnelsId);
                    break;

            }

           
            return View(ps.ToList());
        }

从上面的代码可以看出,我们总共列出了5种数据排列方式,默认排列方式、按薪水高低两种排列方式、按入职日期早晚两种排列方式。

在视图里面我们也要做一下修改:

 
        
   @Html.DisplayNameFor(model => model.Name)
        
        
          @Html.ActionLink("薪水", "Index", new { sortOrder = ViewBag.PaySortPam })  
        
        
           @Html.ActionLink("入职日期", "Index", new { sortOrder = ViewBag.DateSort })
        
        
    
ASP.NET MVC:排序、搜索、分页以及多对多数据库_第2张图片
mark

这样就好了,完成了我们的排序功能。

下面,我们下面来做一个搜索名称的搜索框,打开视图,加入下面的代码

@using (Html.BeginForm())
{ 
  

Find By Name: @Html.TextBox("SearchString")

}
ASP.NET MVC:排序、搜索、分页以及多对多数据库_第3张图片
mark

看起来还不错,再到控制器里面修改代码:

 public ActionResult Index(string sortOrder,string searchString)
        {
            var ps = from s in db.Personnels select s;
            if (!string.IsNullOrEmpty(searchString)) {
                ps = ps.Where(s => s.Name.ToUpper().Contains(searchString.ToUpper()));
            }
   ...省掉重复代码
        }
ASP.NET MVC:排序、搜索、分页以及多对多数据库_第4张图片
mark

不错,这个功能也能用了。

分页需要到NuGet下载PagedList.Mvc 包,安装完成以后有提示

ASP.NET MVC:排序、搜索、分页以及多对多数据库_第5张图片
mark

在控制器中增加一句:using PagedList;

由于增加了分页包,代码修改量比较大,下面将全部代码奉上。首先修改自控制器:

 public ActionResult Index(string sortOrder, string currentFilter, string searchString, int? page)
        {
            ViewBag.CurrentSort = sortOrder;
            ViewBag.PaySortPam = sortOrder == "pay" ? "pay_desc" : "pay";
            ViewBag.DateSort = sortOrder == "date" ? "date_desc" : "date";
            if (searchString != null) { page = 1; } else { searchString = currentFilter; }
            ViewBag.CurrentFilter = searchString;

            var ps = from s in db.Personnels select s;
            if (!string.IsNullOrEmpty(searchString))
            {
                ps = ps.Where(s => s.Name.ToUpper().Contains(searchString.ToUpper()));
            }
            switch (sortOrder)
            {
                case "pay_desc":
                    ps = ps.OrderByDescending(s => s.Pay);
                    break;
                case "pay":
                    ps = ps.OrderBy(s => s.Pay);
                    break;
                case "date_desc":
                    ps = ps.OrderByDescending(s => s.Date);
                    break;
                case "date":
                    ps = ps.OrderBy(s => s.Date);
                    break;
                default:
                    ps = ps.OrderByDescending(s => s.PersonnelsId);
                    break;

            }

            int pageSize = 3;
            int pageNumber = (page ?? 1);
            return View(ps.ToPagedList(pageNumber, pageSize));
        }

视图页全部代码:

@using PagedList.Mvc;
@model PagedList.IPagedList

@{
    ViewBag.Title = "Index";
}

Index

@using (Html.BeginForm("Index","Personnels", FormMethod.Get)) {

Find By Name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)

} @foreach (var item in Model) { }
名称 @Html.ActionLink("薪水", "Index", new { sortOrder = ViewBag.PaySortPam, currentFilter = ViewBag.CurrentFilter }) @Html.ActionLink("入职日期", "Index", new { sortOrder = ViewBag.DateSort, currentFilter = ViewBag.CurrentFilter })
@Html.DisplayFor(modelItem => item.Name) @Html.DisplayFor(modelItem => item.Pay) @Html.DisplayFor(modelItem => item.Date) @Html.ActionLink("Edit", "Edit", new { id = item.PersonnelsId }) | @Html.ActionLink("Details", "Details", new { id = item.PersonnelsId }) | @Html.ActionLink("Delete", "Delete", new { id = item.PersonnelsId })

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 }))
ASP.NET MVC:排序、搜索、分页以及多对多数据库_第6张图片
mark

测试通过。

好,现在已经基本实现了员工表的基本功能,现在,我们来新建一个Tasks任务表

public class Tasks
    {
        public int TasksId { get; set; }
        [Required(ErrorMessage = "请输入名称。")]
        [StringLength(160, MinimumLength = 4)]
        [Display(Name = "名称")]
        public string Name { get; set; }

        public virtual ICollection Taskspersonnels { get; set; }
    }

同时修改一下Personnels类:

public class Personnels
    {
        public int PersonnelsId { get; set; }
        [Required(ErrorMessage = "请输入名称。")]
        [StringLength(160, MinimumLength = 1)]
        [Display(Name = "名称")]
        public string Name { get; set; }
        [Required(ErrorMessage = "请输入薪水。")]
        [Display(Name = "薪水")]
        public decimal Pay { get; set; }
        
        [Display(Name = "入职时间")]
        public DateTime Date { get; set; }

        public virtual ICollection Taskspersonnels { get; set; }
    }

现在有员工、有任务,那么要将员工和任务联系起来,就是一个员工任务列表,是一个多对多的数据库关系。一个员工执行多项任务,一个任务由多个员工执行。如果没有Tasksdate(任务执行时间)的话,这个类可以不用建立。因为它只有两个外键。

 public class Taskspersonnel
    {
        public int TaskspersonnelId { get; set; }
        public int PersonnelsId { get; set; }
        public int TasksId { get; set; }
        
        public DateTime Tasksdate { get; set; }

        public virtual Personnels personnels { get; set; }
        public virtual Tasks tasks { get; set; }
    }

运行生成解决方案后,对这两个实体类新建控制器。

先对Tasks填入一些测试数据。

然后运行/Taskspersonnels/Create:

ASP.NET MVC:排序、搜索、分页以及多对多数据库_第7张图片
mark

因为最后一个日期格式,如果这样直接让用户输入,有可能会输错、报错。所以我们还是找一个日历包给它好了。

ASP.NET MVC:排序、搜索、分页以及多对多数据库_第8张图片
mark

安装JQuery.UI.Widgets.Datepicker,我在安装过程中发生了BUG,所以我直接去JQuery.UI官网上下载。

只要将jquery-ui.min.js和jquery-ui.css引入项目里面,对日期项的TEXT做一下修改

 @Html.EditorFor(model => model.Tasksdate, new { htmlAttributes = new { @class = "form-control datepick"} })

最后,在该视图中加入JQuery代码,完成!


ASP.NET MVC:排序、搜索、分页以及多对多数据库_第9张图片
mark

谢谢大家。转帖的时候请把凉风有兴或者AlexZeng.net进行署名。本文版权声明:自由转载-非商用-以非衍生-保持署名(创意共享3.0许可证)

你可能感兴趣的:(ASP.NET MVC:排序、搜索、分页以及多对多数据库)