开发者社区> 天才小龙> 正文

EF 之 MVC 排序,查询,分页 Sorting, Filtering, and Paging For MVC About EF

简介: 最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来。    十年河东十年河西,莫欺少年穷    学无止境,精益求精    上篇博客我们学习了EF CodeFirst增删改查之‘CRUD’,今儿,我们来探讨下MVC下的EF 排序、查询、分页操作    在此,本人先从分页说起    话说,做过webForm项目的程序员用AspNetPage.
+关注继续查看

   最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来。

   十年河东十年河西,莫欺少年穷

   学无止境,精益求精

   上篇博客我们学习了EF CodeFirst增删改查之‘CRUD’,今儿,我们来探讨下MVC下的EF 排序、查询、分页操作

   在此,本人先从分页说起

   话说,做过webForm项目的程序员用AspNetPage.DLL做过分页,做过EasyUI框架的程序员,用JS AJAX请求分页,那么,MVC 程序员用什么进行分页呢?

   当然,MVC程序亦可以使用上述方式进行分页

   但是......

   原始的分页我们要写大量的代码,或者还需要使用存储过程,在此,小弟贴一个分页的存储过程<也是一个通用的分页存储过程>,贴出这段代码的目的只有一个:让大家做一个比较。

   下面,我仅仅贴出SQL端Proc的代码

GO
/****** 对象:  StoredProcedure [dbo].[ZXL_GetPageData]    脚本日期: 11/26/2016  ******/
SET ANSI_NULLS ON
GO 
 SET QUOTED_IDENTIFIER ON 
 GO



CREATE PROCEDURE [dbo].[ZXL_GetPageData]
(
    @TableName  varchar (500), --要进行分页的表,也可以用联接,如dbo.employee或dbo.employee INNER JOIN dbo.jobs ON (dbo.employee.job_id=dbo.jobs.job_id)
    @Fields  varchar(3000)='*', --表中的字段,可以使用*代替
    @OrderField  varchar(500), --要排序的字段
    @sqlWhere varchar(500)=NULL, --WHERE子句
    @pageSize int, --分页的大小
    @pageIndex int, --要显示的页的索引
    @TotalPage int output, --页的总数
    @RecordCount int output --总记录数
)
as

begin

    Begin Tran

    Declare @sql nvarchar(4000);
    Declare @totalRecord int; --记录总数

    if (@sqlWhere IS NULL or @sqlWhere = '') set @sql = 'select @totalRecord = count(*) from ' + @TableName 
    else
       
    
       set @sql = 'select @totalRecord = count(*) from ' + @TableName + ' where ' + @sqlWhere
    --执行sql语句得到记录总数
    EXEC sp_executesql @sql,N'@totalRecord int OUTPUT',@totalRecord OUTPUT 
    select @TotalPage=CEILING((@totalRecord+0.0)/@PageSize)
    select @RecordCount=CEILING(@totalRecord)
    --根据特定的排序字段为为行分配唯一ROW_NUMBER的顺序
    if (@sqlWhere IS NULL or @sqlWhere = '')
       set @sql = 'select * from (select ROW_NUMBER() over(order by ' + @OrderField + ') as rowId,' + @Fields + ' from ' + @TableName
    else
       set @sql = 'select * from (select ROW_NUMBER() over(order by ' + @OrderField + ') as rowId,' + @Fields + ' from ' + @TableName + ' where ' + @SqlWhere
    --确保当前页的索引在合理的范围之内

    if @PageIndex<=0 
       Set @pageIndex = 1
    if @pageIndex>@TotalPage
       Set @pageIndex = @TotalPage
    --得到当前页在整个结果集中准确的ROW_NUMBER值

    Declare @StartRecord int
    Declare @EndRecord int
    set @StartRecord = (@pageIndex-1)*@PageSize + 1
    set @EndRecord = @StartRecord + @pageSize - 1

    --输出当前页中的数据

    set @Sql = @Sql + ') as t' + ' where rowId between ' + Convert(varchar(50),@StartRecord) + ' and ' +   Convert(varchar(50),@EndRecord)

    Exec(@Sql)
    If @@Error <> 0

       Begin
           RollBack Tran
           Return -1
       End
    Else
       Begin
           Commit Tran
           Return @totalRecord
       End    
End

   今天,我们换个口味,来讲述下另外一种全新的分页

   首先,添加NuGet引用,搜索:pagedList

   

   然后,在我们的Controller中添加:using PagedList;

   如果我们成功添加了NuGet  PagedList引用,那么,在我们的Content文件夹中就会生成一个分页的CSS文件<嘻嘻,微软不愧是世界老大哥,技术领先别人一大截,我是越来越喜欢微软了>

   截止到此,准备工作也就基本做好了,下面我从后端和前端进行说明:

   后端代码如下:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using System.Linq;
using EF_Test.DAL;
using System.Data;
using PagedList;

namespace EF_Test.Controllers
{
    public class HomeController : Controller
    {
        private StudentContext db = new StudentContext();
        /// <summary>
        /// 简单分页演示
        /// </summary>
        /// <param name="page">页码</param>
        /// <returns></returns>
        public ActionResult Index2(int page = 1)//查询所有学生数据
        {
            return View(db.Students.OrderBy(item => item.Id).ToPagedList(page, 9));
        }
    }
}

 

   参数Page是从前端发送的,代表页码,数字9代表每页的数量,在分页的过程中,我们必须得使用OrderBy进行排序,否则程序会出错。

   前端代码如下:

@model PagedList.IPagedList<EF_Test.DAL.Student>
@using PagedList.Mvc
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@section css{
    <link href="~/Content/PagedList.css" rel="stylesheet" />
    <style type="text/css">
        body {
            font-size: 12px;
            font-family: "微软雅黑";
            color: #555;
            position: relative;
            background: #fff;
        }

        a {
            text-decoration: none;
            color: #555;
        }

        #tbList {
            border: 1px solid none;
            width: 800px;
            margin: 10px auto;
            border-collapse: collapse;
        }

            #tbList th, td {
                border: 1px solid #ccc;
                padding: 5px;
                text-align: center;
            }

        tfoot tr td {
            border: none;
        }
    </style>
}

@using (Html.BeginForm("Index", "Home", FormMethod.Get))
{
    <div style="text-align: center;">
        <h1>Mvc分页例子</h1>
        <table id="tbList">

           
            <tbody>
                @if (Model.Count() != 0)
                {  
                    <tr>
                        <th>姓名
                        </th>
                        <th>性别
                        </th>
                        <th>学号
                        </th>
                    </tr>
                    foreach (var item in Model)
                    {   
                    <tr style="text-align: center;">
                        <td>
                            @Html.DisplayFor(modelItem => item.Name)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Sex)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.StudentNum)
                        </td>
                    </tr>  
                    }

                }
            </tbody>
            <tfoot>
                <tr>
                    <td colspan="5">
                        <div class="">
                            @if (Model != null)
                            {  
                                <span style="height: 20px; line-height: 20px;">共 @Model.TotalItemCount.ToString() 条记录,当前第 @Model.PageNumber 页/共 @Model.PageCount 页 </span>  
                                @Html.PagedListPager(Model, page => Url.Action("Index", new { page }), new PagedListRenderOptions() { LinkToFirstPageFormat = "首页", LinkToNextPageFormat = "下一页", LinkToPreviousPageFormat = "上一页", LinkToLastPageFormat = "末页", DisplayItemSliceAndTotal = false, MaximumPageNumbersToDisplay = 3 })    
                            }
                        </div>
                    </td>
                </tr>
            </tfoot>
        </table>
    </div>
}

   前端没什么好说的,大家自己测试,运行结果如下

   

   至此,MVC分页也就讲完了,下面我们来探讨排序的查询的问题

   好吧,由于小弟还没吃饭,就不作说明了,直接上代码:

   前端变更如下:

@model PagedList.IPagedList<EF_Test.DAL.Student>
@using PagedList.Mvc

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@section css{
    <link href="~/Content/PagedList.css" rel="stylesheet" />
    <style type="text/css">
        body {
            font-size: 12px;
            font-family: "微软雅黑";
            color: #555;
            position: relative;
            background: #fff;
        }

        a {
            text-decoration: none;
            color: #555;
        }

        #tbList {
            border: 1px solid none;
            width: 800px;
            margin: 10px auto;
            border-collapse: collapse;
        }

            #tbList th, td {
                border: 1px solid #ccc;
                padding: 5px;
                text-align: center;
            }

        tfoot tr td {
            border: none;
        }
    </style>
}

@using (Html.BeginForm("Index", "Home", FormMethod.Get))
{
    <div style="text-align: center;">
        <h1>Mvc分页例子</h1>
        <table id="tbList">

           
            <tbody>
                @if (Model.Count() != 0)
                {  
                    <tr>
                        <th>姓名
                        </th>
                        <th>性别
                        </th>
                        <th>学号
                        </th>
                    </tr>
                    foreach (var item in Model)
                    {   
                    <tr style="text-align: center;">
                        <td>
                            @Html.DisplayFor(modelItem => item.Name)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Sex)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.StudentNum)
                        </td>
                    </tr>  
                    }

                }
            </tbody>
            <tfoot>
                <tr>
                    <td colspan="5">
                        <div class="">
                            @if (Model != null)
                            {  
                                <span style="height: 20px; line-height: 20px;">共 @Model.TotalItemCount.ToString() 条记录,当前第 @Model.PageNumber 页/共 @Model.PageCount 页 </span>  
                                @Html.PagedListPager(Model, page => Url.Action("Index", new { page }), new PagedListRenderOptions() { LinkToFirstPageFormat = "首页", LinkToNextPageFormat = "下一页", LinkToPreviousPageFormat = "上一页", LinkToLastPageFormat = "末页", DisplayItemSliceAndTotal = false, MaximumPageNumbersToDisplay = 3 })    
                            }
                        </div>
                    </td>
                </tr>
            </tfoot>
        </table>
    </div>
}

   说明几点:

   查询使用的是表单Get请求、

   多加了两个文本框和一个sumbit按钮,用作查询

   姓名和学号做成<A>标签,用作排序,例如:点击姓名,按照姓名升序排,再次点击,按照姓名降序排,同理点击学号

   后端代码如下:

       /// <summary>
       /// 查询 排序 分页
       /// </summary>
       /// <param name="sortOrder">排序字段 默认Id desc</param>
       /// <param name="stuName">搜索框 学生姓名 模糊查询</param>
       /// <param name="stuNum">搜索框 学生学号 精确查询</param>
       /// <param name="page">页码</param>
       /// <returns></returns>
        public ActionResult Index(string sortOrder, string stuName, string stuNum, int page = 1)//查询所有学生数据
        {
            //初始化排序-默认排序
            ViewBag.NameSortParm = "NameAsc";
            ViewBag.StumSortParm = "StumAsc";
            //根据click 更改排序
            if (!string.IsNullOrEmpty(sortOrder))
            {
                if (sortOrder.Contains("Name"))
                {
                    if (sortOrder.Equals("NameAsc"))
                    {
                        sortOrder = "NameDesc";
                        ViewBag.NameSortParm = sortOrder;
                    }
                    else
                    {
                        sortOrder = "NameAsc";
                        ViewBag.NameSortParm = sortOrder;
                    }
                }
                if (sortOrder.Contains("Stum"))
                {
                    if (sortOrder.Equals("StumAsc"))
                    {
                        sortOrder = "StumDesc";
                        ViewBag.StumSortParm = sortOrder;
                    }
                    else
                    {
                        sortOrder = "StumAsc";
                        ViewBag.StumSortParm = sortOrder;
                    }
                }
            }
            //}
            //查询全部数据
            var students = from s in db.Students
                           select s;
            //根据查询条件检索
            if (!string.IsNullOrEmpty(stuName))
            {
                //根据姓名模糊查询
                students = students.Where(s => s.Name.Contains(stuName));
            }
            if (!string.IsNullOrEmpty(stuNum))
            {
                //根据学号精确查询
                students = students.Where(s => s.StudentNum==stuName);
            }
            //排序处理
            switch (sortOrder)
            {
                case "NameDesc":
                    students = students.OrderByDescending(item=>item.Name);
                    break;
                case "NameAsc":
                    students = students.OrderBy(item => item.Name);
                    break;
                case "StumAsc":
                    students = students.OrderBy(s => s.StudentNum);
                    break;
                case "StumDesc":
                    students = students.OrderByDescending(s => s.StudentNum);
                    break;
                default:
                    students = students.OrderByDescending(s => s.Id);
                    break;
            }
            return View(students.ToPagedList(page, 9));//
        }

   运行结果:

   默认排序:ID 倒序排列

   

   点击姓名,按照姓名倒序排列,如下:

   再次点击姓名,按照姓名升序排列、

   同理,点击学号,不做演示

   输入姓名,进行模糊查询

   同理,输入学号进行精确查询,不做演示!

   但是这种方式有个最大的弊端,就是每次都必须查询所有数据,当数据表数据很多时,例如有100W条记录,那么这种方式相率会非常低下。解决方法请参考我的博客:http://www.cnblogs.com/chenwolong/p/6913915.html

   吃饭喽,

   @陈卧龙的博客

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
一起谈.NET技术,ASP.NET MVC中对数据进行排序的方法
  本系列是讲解如何在asp.net mvc中对数据进行展示、排序、分页等的系列文章。在上周的文章中,一步一步教会了大家如何使用ASP.NET MVC框架去的展示数据。在上周的文章中,我们先用Visual Studio创建了一个新的ASP.NET MVC应用程序,接着连接到了Northwind数据库,并展示了如何使用微软的LINQ-SQL的工具去访问数据库中的数据,接着指导如何去实现视图层去展示产品信息及如何设计控制器。
884 0
数据分页时每页首条记录索引如何计算
现在有8条数据,数据库中第一条索引是0,也就是每条数据的索引分别是0,1,2,3,4,5,6,7 。 现在要求每页是2条也就是pagesize = 2,当前页为currentPage。   模拟分页:0 1 | 2 3 | 4 5 | 6 7 第1页currentPage = 1,pagesize = 2,首条记录索引为0,(1 - 1) * 2 第2页currentPage =
915 0
Contoso 大学 - 3 - 排序、过滤及分页
原文 Contoso 大学 - 3 - 排序、过滤及分页 目录 Contoso 大学 - 使用 EF Code First 创建 MVC 应用  原文地址:http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application 在上一个课程中,我们已经学习了如何使用 EF 对 Student 实体进行增、删、改、查处理。
1025 0
+关注
天才小龙
陈卧龙,河南人,现居苏州,擅长NET开发,三层多层架构,EF框架,针对大数据,高并发有一定的研究!
125
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载