阅读本文你的收获
- 实现一个SQL Server的通用分页存储过程
- 学会用EF Core去调用分页存储过程
在之前的文章 EFCore基础之如何执行原生SQL语句 中,我们遗留了一个课题,那就是EF Core如何执行存储过程,这次我们就来分享一下用法。
本篇文档中案例的开发环境:
数据库:MS SQL Server 2014
平台版本是:.NET6
开发工具:Visual Studio 2022
一. 编写分页存储过程
1. 在MS SQL Server中定义一个单表 通用分页查询存储过程
-- 创建分页存储过程
create proc p_pageList
@tableName nvarchar(100), -- 表名
@fields nvarchar(500), -- 查询字段
@where nvarchar(500), -- 过滤条件
@orderby nvarchar(100), -- 排序字段
@pageIndex int, -- 页码
@pageSize int, -- 每页条数
@totalCount int output -- 返回的总条数
as
begin
-- 声明局部变量
declare @strSql nvarchar(max)
declare @strCount nvarchar(max)
-- 获取符合条件的总条数
set @strCount = N'select @totalCount=count(1) from ' + @tableName
-- 拼接查询条件
if @where <> ''
set @strCount = @strCount + ' where ' + @where
--print(@strCount)
exec sp_executesql @strCount, N'@totalCount int output', @totalCount output
-- 获取结果集
set @strSql = 'select ' + @fields + ' from ' + @tableName
-- 拼接查询条件
if @where <> ''
set @strSql = @strSql + ' where ' + @where
set @strSql = @strSql
+' order by '+ @orderby
+' offset '+str((@pageIndex-1)*@pageSize) +' rows fetch next '+ str(@pageSize) +' rows only'
--print(@strSql)
--执行sql语句
exec(@strSql)
end
go
2. 测试存储过程
-- 测试存储过程
declare @total int
exec p_pageList '[User] as t1','t1.UserId, t1.UserName, t1.TelPhone', ' t1.username like ''%a%''','t1.UserId asc',1,2,@total output
select @total
二. EF Core执行分页存储过程
1. 添加EFCoreExtentions.cs这个文件到项目中。
该扩展方法可以到我的资源列表中下载
2. 编写 某个模块的仓储接口
此例中的IRepository为泛型仓储接口,声明一个用户模块的仓储接口
/// <summary>
/// 用户模块的仓储接口
/// </summary>
public interface IUserRepository : IRepository<User>
{
(int total, List<User> list) GetPage(int pageIndex, int pageSize, string where, string orderby);
}
3. 在仓储实现类中,调用Query扩展方法去执行存储过程
/// <summary>
/// 用户的仓储接口实现类
/// </summary>
public class UserRepository: EfRepository<User>, IUserRepository
{
private readonly MyDbContext _db;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="db"></param>
public UserRepository(MyDbContext db):base(db)
{
_db = db;
}
/// <summary>
/// 获取用户分页数据
/// </summary>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="where"></param>
/// <param name="orderby"></param>
/// <returns>元组(总条数,分页结果集合)</returns>
public (int total, List<User> list) GetUserPage(int pageIndex, int pageSize, string where, string orderby)
{
//定义SqlParameter参数数组
SqlParameter[] paras = new SqlParameter[] {
new SqlParameter("@tableName", "[User]"),
new SqlParameter("@fields", "*"),
new SqlParameter("@where", where),
new SqlParameter("@pageIndex", pageIndex),
new SqlParameter("@pageSize", pageSize),
new SqlParameter("@orderby", orderby),
new SqlParameter("@totalCount", DbType.Int32)
};
paras[6].Direction = ParameterDirection.Output; //最后一个参数为输出参数
//执行,万能存储过程,获取分页结果集
var list = _db.Query<User>("p_pageList", //存储过程的名字
CommandType.StoredProcedure, //命令类型为存储过程
paras); //传参
//获取总条数
int total = (int)paras[6].Value;
return (total, list); //返回元组
}
}
//在应用服务层里,依赖注入UserRepository
IUserRepository _userRepository;
//...
//调用分页查询方法
var result = _userRepository.GetUserPage(1, 10, "username like '%李%'", " CreatedTime Desc")
//...
本次分享就这么多,希望对你有帮助。欢迎多点赞+评论+关注。