mvc,EntityFramework调用分页存储过程

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

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

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

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
            SET @sqlStr=N‘SELECT ‘+@fieldName+‘ 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[8];
                //页索引
                paras[0] = new SqlParameter("pageIndex", DbType.Int32);
                paras[0].Value = pageinationInfo.PageIndex;
                //页大小
                paras[1] = new SqlParameter("pageSize", DbType.Int32);
                paras[1].Value = pageinationInfo.PageSize;
                //表名
                paras[2] = new SqlParameter("tableName", DbType.String);
                paras[2].Value = pageinationInfo.TableName;
                //查询字段
                //EF仅支持返回返回某个表的全部字段,以便转换成对应的实体,无法支持返回部分字段的情况...???
                paras[3] = new SqlParameter("fieldName", DbType.String);
                paras[3].Value = pageinationInfo.FieldName;
                //where条件
                paras[4] = new SqlParameter("whereCondition", DbType.String);
                paras[4].Value = pageinationInfo.WhereCondition;
                //order条件
                paras[5] = new SqlParameter("orderCondition", DbType.String);
                paras[5].Value = pageinationInfo.OrderCondition;
                //总数
                paras[6] = new SqlParameter("totalCount", DbType.Int32);
                paras[6].Value = pageinationInfo.TotalCount;
                paras[6].Direction = ParameterDirection.Output;
                //总页数
                paras[7] = new SqlParameter("totalPages", DbType.Int32);
                paras[7].Value = pageinationInfo.TotalPages;
                paras[7].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[6].Value;
                data.TotalPages= (int)paras[7].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 = 1;
pageination.PageSize = 15;
pageination.FieldName = "*";
pageination.OrderCondition = "PostTime desc";
pageination.WhereCondition = "Isdelete=0";
var data = pageImpl.GetPageinationData<NewsInfo>(pageination);

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

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

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

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

各位大神如果有方法的话,希望指教一下,谢谢!

时间: 2024-11-05 23:37:44

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

EntityFramework 4使用存储过程分页

1 CREATE PROC usp_OrgPage_SQL 2 @pageIndex INT, 3 @pageSize INT, 4 @totalCount INT OUTPUT 5 AS 6 BEGIN 7 SET @totalCount = (SELECT COUNT(*) FROM dbo.Organization) 8 SELECT * FROM 9 ( 10 SELECT *,ROW_NUMBER() OVER(ORDER BY OrganizationID DESC)AS row F

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

一.创建带有输出参数的分页存储过程 1 use StudentMISDB 2 go 3 select * from Course 4 alter table Course 5 add IsDelete int not null default 0 6 go 7 select * from Course where IsDelete=1 8 9 --update Course set IsDelete=0 10 11 ---循环 添加数据 12 --declare @index int 13 --

调用MySql 分页存储过程带有输入输出参数

1 Create PROCEDURE getuser 2 ( 3 IN pageIndex INT, 4 IN pageSize INT, 5 OUT count INT 6 ) 7 8 BEGIN 9 declare pindex int DEFAULT (pageIndex-1)*pageSize; 10 11 select * from lc_user order by id LImit pindex,pageSize; 12 13 SELECT COUNT(id) INTO count

微软企业库5.0 调用 MySql 分页存储过程

1.需要完成两个前置条件后才可以使用 微软企业库5.0 调用 MySql 存储过程 微软企业库5.0 支持 MySql MySql 分页存储过程 2.需要添加一个继承 IParameterMapper 接口的类分配查询参数 using System.Data; using System.Data.Common; using Microsoft.Practices.EnterpriseLibrary.Data; using Grass.Extend; namespace Grass.MySqlDa

千万级数据分页存储过程 asp.net页面调用分页全过程

下方有调用过程 从程序中考虑:比如用数据缓冲和连接池技术从数据库服务器端考虑:比如csdn只选出前300行纪录,因为用户不需要那么多纪录.你也不必把1000万条全部分页.你也不必把纪录放在一个表中,一年(太多就一个月)的数据放一张表或定期把历史数据导出到数据数据仓库中,不要用一张表装1000万条记录.做好索引.优化查询!尽量少用模糊查询,避免表扫描.不能让客户端连续多次搜索(csdn就是) 千万级的数据库,有分页的意义吗?对于用户来说就是信息的海洋了,去看看Google怎么做的吧,根本就不存在如

ADO调用分页查询存储过程

一.分页存储过程 ----------使用存储过程编写一个分页查询----------------------- set nocount off  --关闭SqlServer消息 --set nocount on  --开启SqlServer消息 gocreate proc usp_getMyStudentsDataByPage --输入参数@pagesize int=7,--每页记录条数@pageindex int=1,--当前要查看第几页的记录 --输出参数@recordcount int

【SQLSERVER学习笔记】分页存储过程+调用

1 USE [数据库名] 2 GO 3 4 SET ANSI_NULLS ON 5 GO 6 7 SET QUOTED_IDENTIFIER ON 8 GO 9 CREATE PROCEDURE [dbo].[存储过程名] 10 @pageIndex INT, 11 @pageSize INT, 12 @totalCount INT OUTPUT 13 AS 14 SET NOCOUNT ON 15 16 DECLARE @PageStart INT 17 DECLARE @PageEnd IN

sql server 分页存储过程

随着信息时代的发展信息系统的使用越来越多,信息量越来越大:当信息量越来越大,这在数据 展示,特别是报表这块对系统展现效率要求越来越高,对于千万级数据量的展示必须得使用分页来展示. www.2cto.com If object_id('SP_Pagination')is not null drop proc SP_Pagination go Create PROCEDURE SP_Pagination /**//* *****************************************

真正通用的SQL分页存储过程

关于SQL分页的问题,网上找到的一些SQL其实不能真正做到通用,他们主要是以自增长ID做为前提的.但在实际使用中,很多表不是自增长的,而且主键也不止一个字段,其实我们稍做改进就可以达到通用.这里还增加了索引,以方便大数据量的使用(代码中是先抓到临时表的,从性能上说如果采用自增长式的ID表,当然可以不使用临时表以达到性能的提升).以下代码的SP是经过我们项目使用通过的.因朋友问及此问题,我就放在这里供大家分享,如各位大侠有更好的方法,也请告诉我.在这里先感谢各位了. 1 CREATE PROCED