此文讲述mvc4+entityframework6+sqlserver2008环境下调用存储过程,实现分页。

1、分页存储过程代码如下:

分页原理用的row_number()和over()函数实现(没有用top、not in,因为性能低;sqlserver2012有新特性,用offset、fetch实现)。

这里支持多表查询分页。

SET ANSI_NULLS ON
GO SET QUOTED_IDENTIFIER ON
GO CREATE PROCEDURE [dbo].[Procedure_SpiltPage]
( @pageIndex INT =1, --页索引
@pageSize INT =10, --页大小
@tableName NVARCHAR(100), --表名
@fieldName NVARCHAR(200) ='*', --查询字段
@whereCondition NVARCHAR(800) ='1=1', --where条件
@orderCondition NVARCHAR(200), --order条件
@recordTotal INT OUTPUT, --输出记录总数
@pageCount INT OUTPUT --输出分页数
) AS
BEGIN
DECLARE @sqlStr NVARCHAR(1000); SET NOCOUNT ON; --不返回计数 --返回记录总数
SET @sqlStr = 'SELECT @recordTotal = COUNT(*) FROM '+@tableName+' WHERE '+@whereCondition
EXEC sp_executesql @sqlStr,N'@recordTotal INT OUTPUT',@recordTotal OUTPUT
SET @pageCount=(@recordTotal+@pageSize-1)/@pageSize --查询列表
--如果是第一页
IF (@pageIndex<=1)
BEGIN
--N'表示强制转换为Unicode字符,不会乱码
SET @sqlStr=N'SELECT TOP '+CAST(@pageSize AS VARCHAR)+' '+@fieldName+' FROM '+@tableName+' WHERE '+@whereCondition+' ORDER BY '+@orderCondition
END
ELSE
BEGIN
--为了适应多表查询,下面把第一处@fieldName改为*,这里不查询全部字段,因为第二个@fieldName
SET @sqlStr=N'SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY '+@orderCondition+') AS rownum, '
+@fieldName+' FROM '+@tableName+' WHERE '+@whereCondition+') AS myTable WHERE rownum BETWEEN '
+CAST(((@pageIndex-1)*@pageSize+1) AS NVARCHAR)+' AND '+CAST((@pageIndex*@pageSize) AS NVARCHAR)
END EXEC (@sqlStr) SET NOCOUNT OFF;
END GO

存储过程

在数据库中测试,可以如下:

declare @total int
declare @pageCount int
exec Procedure_SpiltPage 1,15,'NewsInfo','*','1=1','PostTime desc',@total output,@pageCount output
select @total as total,@pageCount as pageCounts

执行测试代码

2、分页实现代码:

2.1、分页信息类如下:

namespace WebUI.PageinationService
{
/// <summary>
/// 分页信息类
/// </summary>
public class PageinationInfo
{
/// <summary>
/// 页索引
/// </summary>
public int PageIndex { get; set; }
/// <summary>
/// 页大小
/// </summary>
public int PageSize { get; set; }
/// <summary>
/// 总数
/// </summary>
public int TotalCount { get; set; }
/// <summary>
/// 总页数
/// </summary>
public int TotalPages { get; set; }
/// <summary>
/// 表名
/// </summary>
public string TableName { get; set; }
/// <summary>
/// 主键
/// </summary>
public string KeyName { get; set; }
/// <summary>
/// 查询字段
/// </summary>
public string FieldName { get; set; }
/// <summary>
/// where条件(不带'where')
/// </summary>
public string WhereCondition { get; set; }
/// <summary>
/// 排序条件,如:id desc ,或者:id desc,name asc
/// </summary>
public string OrderCondition { get; set; }
}
}

分页信息类

2.2、分页数据类(用以返回)

namespace WebUI.PageinationService
{
/// <summary>
/// 分页数据类
/// 用以将分页集合和总数,总页数等打包一起返回
/// </summary>
public class PageinationData
{
/// <summary>
/// 总数
/// </summary>
public int TotalCount { get; set; }
/// <summary>
/// 总页数
/// </summary>
public int TotalPages { get; set; } /// <summary>
/// 集合
/// </summary>
public dynamic DataList { get; set; }
}
}

分页数据类

2.3、分页实现类:

namespace WebUI.PageinationService
{
/// <summary>
/// 分页读取数据的实现类
/// </summary>
public class PageinationImplement
{
//数据库上下文实例
private MyDbContext db; public PageinationImplement(MyDbContext dbContext)
{
this.db = dbContext;
} /// <summary>
/// 读取分页数据
/// </summary>
/// <typeparam name="T">实体</typeparam>
/// <param name="pageinationInfo">分页信息类</param>
/// <returns>分页数据</returns>
public PageinationData GetPageinationData<T>(PageinationInfo pageinationInfo) where T : class
{
dynamic result = null;
try
{
#region SqlParameter参数
SqlParameter[] paras = new SqlParameter[];
//页索引
paras[] = new SqlParameter("pageIndex", DbType.Int32);
paras[].Value = pageinationInfo.PageIndex;
//页大小
paras[] = new SqlParameter("pageSize", DbType.Int32);
paras[].Value = pageinationInfo.PageSize;
//表名
paras[] = new SqlParameter("tableName", DbType.String);
paras[].Value = pageinationInfo.TableName;
//查询字段
//EF仅支持返回返回某个表的全部字段,以便转换成对应的实体,无法支持返回部分字段的情况...???
paras[] = new SqlParameter("fieldName", DbType.String);
paras[].Value = pageinationInfo.FieldName;
//where条件
paras[] = new SqlParameter("whereCondition", DbType.String);
paras[].Value = pageinationInfo.WhereCondition;
//order条件
paras[] = new SqlParameter("orderCondition", DbType.String);
paras[].Value = pageinationInfo.OrderCondition;
//总数
paras[] = new SqlParameter("totalCount", DbType.Int32);
paras[].Value = pageinationInfo.TotalCount;
paras[].Direction = ParameterDirection.Output;
//总页数
paras[] = new SqlParameter("totalPages", DbType.Int32);
paras[].Value = pageinationInfo.TotalPages;
paras[].Direction = ParameterDirection.Output;
#endregion string sql = "Procedure_SpiltPage @pageIndex,@pageSize,@tableName,@fieldName,@whereCondition,@orderCondition,@totalCount output,@totalPages output";
var list = db.Database.SqlQuery<T>(sql, paras).ToList(); PageinationData data = new PageinationData();
data.TotalCount= (int)paras[].Value;
data.TotalPages= (int)paras[].Value;
data.DataList = list; result = data;
}
catch(Exception e)
{
throw;
} return result;
}
}
}

分页实现类

3、调用并返回数据:

PageinationImplement pageImpl = new PageinationImplement(db);
PageinationInfo pageination = new PageinationInfo();
pageination.TableName = "NewsInfo";
pageination.PageIndex = ;
pageination.PageSize = ;
pageination.FieldName = "*";
pageination.OrderCondition = "PostTime desc";
pageination.WhereCondition = "Isdelete=0";
var data = pageImpl.GetPageinationData<NewsInfo>(pageination);

上面的new PageinationImplement(db)中的db是数据库上下文(DbContext实例),

上面的data里包括了分页列表,总记录数,分页页数 信息。

注:本来我执行存储过程,想只查询表的部分字段,结果会报错,暂时只能用*查询所有字段,

网上查说EF暂时仅支持返回返回某个表的全部字段,以便转换成对应的实体,无法支持返回部分字段的情况...

我能想到的方法就是自定义类,不用对应数据库的实体类。

不知道有没有其他方法可以实现,各位大神如果有方法的话,希望指教一下,谢谢!

mvc,EntityFramework调用分页存储过程的更多相关文章

  1. EF框架 与 Dapper框架 调用分页存储过程

    1. SqlServer创建存储过程: --创建存储过程 create proc sp_Show ( @index int, --当前页 @size int, --每页大小 @totalcount i ...

  2. SQLserver 的分页存储过程

      -- 1.建立修改学生数据的存储过程 -- 2.建立根据班级Id和学生姓名模糊查询的分页存储过程,要求正确输出总记录数,总页数-- (输入班学生姓名 计算总记录数 计算总页数) -- @name ...

  3. EntityFramework 4使用存储过程分页

    CREATE PROC usp_OrgPage_SQL @pageIndex INT, @pageSize INT, @totalCount INT OUTPUT AS BEGIN SET @tota ...

  4. 完整的分页存储过程以及c#调用方法

    高效分页存储过程 USE [db] GO /****** 对象: StoredProcedure [dbo].[p_Page2005] 脚本日期: // :: ******/ SET ANSI_NUL ...

  5. Oracle分页存储过程及PLSQL中的调用脚本

    撰写过程:网上搜集测试了好多的Oracle分页存储过程代码,经整理后终于通过测试,特分享给大家 测试步骤:1.运行创建包命令;2.运行创建存储过程命令;3.运行调用分页存储过程语句 测试环境:wind ...

  6. MVC 5 调用存储过程参数配置方法-Procedure or function 'UP_***' expects parameter '@****', which was not supplied.

    MVC 5 调用存储过程参数配置方法-Procedure or function 'UP_***' expects parameter '@****', which was not supplied. ...

  7. Delphi调用SQL分页存储过程实例

    Delphi调用SQL分页存储过程实例 (-- ::)转载▼ 标签: it 分类: Delphi相关 //-----下面是一个支持任意表的 SQL SERVER2000分页存储过程 //----分页存 ...

  8. ADO调用分页查询存储过程

    一.分页存储过程 ----------使用存储过程编写一个分页查询----------------------- set nocount off --关闭SqlServer消息 --set nocou ...

  9. C# 调用带有输出参数的分页存储过程

    一.创建带有输出参数的分页存储过程 use StudentMISDB go select * from Course alter table Course go --update Course set ...

随机推荐

  1. shell-跳板机便捷增加用户及设置密码

    我的需求: 因网络限制,某些客户机ssh到服务器都得使用跳板机进行转一下,每次帮开帐户,不麻烦不难,但总觉得还可以再优. 不多说,直接放shell.很简单 #!/bin/bash #test add ...

  2. DOS、Mac 和 Unix 文件格式+ UltraEdit使用

    文件格式 区分DOS.Mac 和 Unix分别对应三种系统 从文件编码的方式来看,文件可分为ASCII码文件和二进制码文件两种 文件模式 区分ASCII模式和Binary模式  通常由系统决定,大多数 ...

  3. Elasticsearch数据迁移工具elasticdump工具

    1. 工具安装 wget https://nodejs.org/dist/v8.11.2/node-v8.11.2-linux-x64.tar.xz tar xf node-v8.11.2-linux ...

  4. 6 CLR静态构造器

    CLR保证一个类型构造器在每个AppDomain中只执行一次,而且这种执行是线程安全的. 作用: 就是初始化静态成员 比如有几个静态成员需要初始化那你把初始化代码放到哪呢? 放到普通构造函数里,那肯定 ...

  5. C++文件流操作

    #include <iostream> #include <fstream> #include<iostream> using namespace std; int ...

  6. db2 应用的最常见状态(转)

    db2 的应用最常见的状态为UOW Executing, UOW Waiting,  Connect Completed等,这里做一个简单的介绍. UOW全称是Unit Of Work, 可以认为是事 ...

  7. 树剖+线段树||树链剖分||BZOJ2238||Mst

    题面:https://www.lydsy.com/JudgeOnline/problem.php?id=2238 思路:先求个最小生成树,然后就对最小生成树上的边做树剖,依次对非树边进行处理,维护非树 ...

  8. 一窥Spring Cloud Eureka

    在Spring Cloud中Eureka负责服务发现功能.服务发现需要解决如何找到服务提供者在网络中位置的问题. 服务端 在Spring Tool Suite的文件菜单中,点击新建Spring Sta ...

  9. 初试 Entity Framework Core 的多对多映射

    今天在博问中看到一个关于 EF Core 的提问 ef core 2.0 多对多查询的问题,由于还没使用过 EF Core 的多对多映射,于是参考 EF Core 帮助文档快速写了个 .net cor ...

  10. bitcoinj学习记录

    一.密码学相关资料 使用Bouncy Castle生成数字签名.数字信封 ECDH and ECDSA(ECC椭圆曲线算法3) 数字签名算法RSA与 ECDSA的比较与分析 Java密码学 非对称加密 ...