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

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

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

学无止境,精益求精

   上篇博客我们学习了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 倒序排列

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

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

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

输入姓名,进行模糊查询

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

吃饭喽,

@陈卧龙的博客

时间: 2024-10-25 03:52:08

EF 之 MVC 排序,查询,分页 Sorting, Filtering, and Paging For MVC About EF的相关文章

[转]Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application (3 of 10)

本文转自:http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application Download Completed Project The Contoso University sample web application de

动态多条件查询分页以及排序(一)--MVC与Entity Framework版url分页版

一.前言 多条件查询分页以及排序  每个系统里都会有这个的代码 做好这块 可以大大提高开发效率  所以博主分享下自己的6个版本的 多条件查询分页以及排序 二.目前状况 不论是ado.net 还是EF 在做多条件搜索时 都有这类似的代码 这样有几个不好的地方 1.当增加查询条件,需要改代码,对应去写相应的代码. 2.对多表查询以及or的支持 不是很好.而我们很常见的需求不可能是一个表的查询 3. 这样写表示层直接出现 了SQL语句 或者 linq 的拉姆达表达式  这是很不好的 表示层不应该知道数

在ASP.NET MVC中使用Boostrap实现产品的展示、查询、排序、分页

在产品展示中,通常涉及产品的展示方式.查询.排序.分页,本篇就在ASP.NET MVC下,使用Boostrap来实现. 源码放在了GitHub: https://github.com/darrenji/ProductsSearchSortPage 先上效果图: 最上面是搜索和排序,每次点击搜索条件.排序,或者删除搜索条件都会触发异步加载. 中间部分为产品展示,提供了列表和格子这2种显示方式. 最下方为分页. 能实现的功能包括: ○ 点击某一个搜索条件,该搜索条件被选中,选中项以标签的形式显示到"

2016/3/13 七种查询 (普通查询 条件查询 排序查询 模糊查询 统计查询 分组查询 分页查询 )

一句话概括的话,SQL作为结构化查询语言,是标准的关系型数据库通用的标准语言: T-SQL 是在SQL基础上扩展的SQL Server中使用的语言 1,普通查询 #查询Info表中的所有列 select * from Info #查询Info表中的Name和Code列 select Name,Code from Info 2,条件查询 关键字where #查询Info表的左右列 限定范围 列名为p001 select * from Info where 列名="p001" #查询条件之

[原创]java WEB学习笔记92:Hibernate学习之路-- -QBC 检索和本地 SQL 检索:基本的QBC 查询,带 AND 和 OR 的QBC,统计查询,排序,分页

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

Oracle基本语法&amp;&amp;函数&amp;&amp;子查询&amp;&amp;分页查询&amp;&amp;排序&amp;&amp;集合操作&amp;&amp;高级分组函数

一.  数据库 手工---文件管理---数据库 DB:Database 数据库. DBMS:管理数据库的软件.(oracle) 主流关系数据库: 1.      Oracle 2.      DB2 3.      SQL Server 基本没人使 4.      MySQL  基本没人用,免费 Linux 开源,可以发现漏洞补上 Windows服务器会有补丁,数据易泄漏 eclipse 日食 数据表(Table): 表的行(Row):记录 表的列(Column):字段 二.  关系型数据库 一

oracle入门(8)——实战:支持可变参数、多种条件、多个参数排序、分页的存储过程查询组件

[本文介绍] 学了好几天,由于项目需要,忙活了两天,写出了个小组件,不过现在还只能支持单表操作.也没考虑算法上的优化,查询速度要比hibernate只快了一点点,可能是不涉及多表查询的缘故吧,多表的情况下才更快. 经非专业的测试,在有分页的情况下,在300万条数据里面查询的时间保持在0.1秒内.相同查询条件+分页的情况下,hibernate 用时0.3秒内. 不分页的条件下,查出来的数据越多,时间越长,时间长的话,跟hibernate相相比就没什么优势了. [思路] 我的思路是从java传来”字

在ASP.NET MVC5中实现具有服务器端过滤、排序和分页的GridView

背景 在前一篇文章<[初学者指南]在ASP.NET MVC 5中创建GridView>中,我们学习了如何在 ASP.NET MVC 中实现 GridView,类似于 ASP.NET web 表单的功能.通过前文,我们已经了解到使用 jQuery 插件的数据表可以很容易地实现具有搜索.排序和分页等重要功能的表格. 前文中需要注意的是,所有通过插件实现的特性都是客户端的,这意味着所有的数据都首先在页面载入,然后由插件来处理客户端搜索.分页和排序的数据.如果数据表不是特别大,这么做是可以的:但是,如

【数据库】优化排序 &amp;&amp; 高效分页

例子: select <cols> from profiles where sex = 'M' order by rating  limit 10; 同时使用了order by,limit,如果没有索引会很慢.而sey的选择又很低,可以增加一些特殊的索引来做排序.例如,创建(sex,rating)索引. 即使有索引,如果用户需要翻页,并且翻页到比较靠后时查询也可能非常慢. 下面这个查询就通过order by 和limit偏移量的组合翻页到很靠后面的时候: mysql>select <