EFCore基础之如何执行数据库存储过程

阅读本文你的收获

  1. 实现一个SQL Server的通用分页存储过程
  2. 学会用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这个文件到项目中。

该扩展方法可以到我的资源列表中下载

EFCore基础之如何执行数据库存储过程_第1张图片

2. 编写 某个模块的仓储接口

此例中的IRepository为泛型仓储接口,声明一个用户模块的仓储接口

/// 
/// 用户模块的仓储接口
/// 
public interface IUserRepository : IRepository<User>
{
    (int total, List<User> list) GetPage(int pageIndex, int pageSize, string where, string orderby);
}

3. 在仓储实现类中,调用Query扩展方法去执行存储过程

/// 
/// 用户的仓储接口实现类
/// 
public class UserRepository: EfRepository<User>, IUserRepository
{
    private readonly MyDbContext _db;

    /// 
    /// 构造函数
    /// 
    /// 
    public UserRepository(MyDbContext db):base(db)
    {
        _db = db;
    }
    
    /// 
    /// 获取用户分页数据
    /// 
    /// 
    /// 
    /// 
    /// 
    /// 元组(总条数,分页结果集合)
    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")
//...

本次分享就这么多,希望对你有帮助。欢迎多点赞+评论+关注。

你可能感兴趣的:(#,ORM框架,.NET后端,数据库,c#,后端,.net)