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 (), --要进行分页的表,也可以用联接,如dbo.employee或dbo.employee INNER JOIN dbo.jobs ON (dbo.employee.job_id=dbo.jobs.job_id)
@Fields varchar()='*', --表中的字段,可以使用*代替
@OrderField varchar(), --要排序的字段
@sqlWhere varchar()=NULL, --WHERE子句
@pageSize int, --分页的大小
@pageIndex int, --要显示的页的索引
@TotalPage int output, --页的总数
@RecordCount int output --总记录数
)
as begin Begin Tran Declare @sql nvarchar();
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<=
Set @pageIndex =
if @pageIndex>@TotalPage
Set @pageIndex = @TotalPage
--得到当前页在整个结果集中准确的ROW_NUMBER值 Declare @StartRecord int
Declare @EndRecord int
set @StartRecord = (@pageIndex-)*@PageSize +
set @EndRecord = @StartRecord + @pageSize - --输出当前页中的数据 set @Sql = @Sql + ') as t' + ' where rowId between ' + Convert(varchar(),@StartRecord) + ' and ' + Convert(varchar(),@EndRecord) Exec(@Sql)
If @@Error <> Begin
RollBack Tran
Return -
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 = )//查询所有学生数据
{
return View(db.Students.OrderBy(item => item.Id).ToPagedList(page, ));
}
}
}
参数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: #;
position: relative;
background: #fff;
} a {
text-decoration: none;
color: #;
} #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() != )
{
<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="">
<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 = })
}
</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: #;
position: relative;
background: #fff;
} a {
text-decoration: none;
color: #;
} #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() != )
{
<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="">
<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 = })
}
</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 = )//查询所有学生数据
{
//初始化排序-默认排序
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, ));//
}
运行结果:
默认排序:ID 倒序排列

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

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

同理,点击学号,不做演示
输入姓名,进行模糊查询

同理,输入学号进行精确查询,不做演示!
但是这种方式有个最大的弊端,就是每次都必须查询所有数据,当数据表数据很多时,例如有100W条记录,那么这种方式相率会非常低下。解决方法请参考我的博客:http://www.cnblogs.com/chenwolong/p/6913915.html
吃饭喽,
@陈卧龙的博客
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-fi ...
- Oracle数据库order by排序查询分页比不分页还慢问题解决办法
简单说下问题,有一个JDBC的查询SQL,分页查询语句中有一个排序order by create_time,理论上来说JDBC查询已经是比较底层的技术了,没有像Hibernate.MyBatis那样又 ...
- 动态多条件查询分页以及排序(一)--MVC与Entity Framework版url分页版
一.前言 多条件查询分页以及排序 每个系统里都会有这个的代码 做好这块 可以大大提高开发效率 所以博主分享下自己的6个版本的 多条件查询分页以及排序 二.目前状况 不论是ado.net 还是EF ...
- 在ASP.NET MVC中使用Boostrap实现产品的展示、查询、排序、分页
在产品展示中,通常涉及产品的展示方式.查询.排序.分页,本篇就在ASP.NET MVC下,使用Boostrap来实现. 源码放在了GitHub: https://github.com/darrenji ...
- ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第五章:排序、分页和路由
本章的重点是对产品信息增加排序和分页的功能,以及使用ASP.NET Routing特性添加更加友好的URL支持. 注意:如果你想按照本章的代码编写示例,你必须完成第四章或者直接从www.apress. ...
- asp.net mvc多条件+分页查询解决方案
开发环境vs2010 css:bootstrap js:jquery bootstrap paginator 原先只是想做个mvc的分页,但是一般的数据展现都需要检索条件,而且是多个条件,所以就变成了 ...
- [原创]java WEB学习笔记92:Hibernate学习之路-- -QBC 检索和本地 SQL 检索:基本的QBC 查询,带 AND 和 OR 的QBC,统计查询,排序,分页
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- 对于Oracle中分页排序查询语句执行效率的比较分析
转自:http://bbs.csdn.net/topics/370033478 对于Oracle中分页排序查询语句执行效率的比较分析 作者:lzgame 在工作中我们经常遇到需要在Oracle中进行分 ...
- lucene 查询+分页+排序
lucene 查询+分页+排序 1.定义一个工厂类 LuceneFactory 1 import java.io.IOException; 2 3 import org.apache.lucene.a ...
随机推荐
- 【BZOJ】2938: [Poi2000]病毒
题意 \(n\)个01病毒串,总长不超过\(30000\).问是否存在无限长的不包含病毒串的01串. 分析 考虑ac自动机,如果不包含病毒串而且无限长也就是说存在一个环(转移和fail树),使得环上不 ...
- 不错的 iOS 开发辅助工具
一,常用 1> iPhone 日志插件iConsole.
- java中的List记录是否完全匹配方法
今天要说的是给List分组,然后用Map来封装,可能你看了以后还是有一些模糊. 先看一下项目结构图: User类是一个VO类,主要逻辑还是在MapTestBak上面. 运行效果: 原理图: 1.在st ...
- linux下定时重启tomcat
工具/原料 linux tomcat 方法/步骤 编写tomcat_shutdown.sh: #!/bin/sh export JAVA_HOME=/home/oracle/jdk1..0_67/ e ...
- jQuery hide()并不等于hide(0)
在实际使用中,经常用hide()函数来隐藏HTML元素,通常是没有什么问题的,但在一次做二级下拉菜单时遇到了问题,后来才发现有时候“speed”是不能省略的,即使“speed=0”,也就是说hide( ...
- web页面实现指定区域打印功能
web页面实现指定区域打印功能 使用CSS,定义一个.noprint的class,将不打印的内容放入这个class内. 详细如下: <style media=print type="t ...
- 重命名PDF打印文件名
Odoo系统默认打印出来的PDF文件都是以当前文档模型对象对应的模板文件名命名的,对用户来说,这样的命名很不友好. 我们希望能够将打印出来的文件名以单号命名,下面是实现这种目的的方法. 在report ...
- HTML 5 服务器发送事件
接收 Server-Sent 事件通知 EventSource 对象用于接收服务器发送事件通知: 实例 var source=new EventSource("demo_sse.php&qu ...
- Daily Scrum 10.24
昨天我们的工作已经全面开始了,本来想等今天(25号)看那个燃尽图和燃速图能不能出来,结果还是没有,就先把我们的Task统计贴上来吧. 今天的Task统计: 至于燃尽图和燃速图的问题已经发老师邮件提问了 ...
- 需要注意学习.net过程的要点
基础部分 C# 基础语法 OOP的概念,面向对象的理解 继承 封装 多态 ASP.NET MVC (Web Form 用的越来越少,如果你不熟悉,可以不看) JavaScript 基础语法 如何在HT ...