You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
7.9 KiB

using System.Linq.Expressions;
namespace CellularManagement.Domain.Repositories.Base;
/// <summary>
/// 查询仓储接口
/// 用于处理数据的读取操作(R:Read)
/// 遵循 CQRS 模式中的查询部分
/// </summary>
/// <typeparam name="T">实体类型,必须是引用类型</typeparam>
/// <remarks>
/// 设计说明:
/// 1. 所有方法都是异步的,因为查询操作需要等待数据库响应
/// 2. 支持分页查询,提高大数据量查询的性能
/// 3. 支持条件查询,使用 LINQ 表达式树构建查询条件
/// 4. 支持排序和包含导航属性
/// </remarks>
public interface IQueryRepository<T> where T : class
{
/// <summary>
/// 根据ID查询单个实体
/// </summary>
/// <param name="id">要查询的实体ID</param>
/// <param name="include">查询条件表达式</param>
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
/// <returns>查询到的实体,如果不存在则返回 null</returns>
/// <remarks>
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
/// 使用主键进行查询,性能最优
/// </remarks>
Task<T?> GetByIdAsync(string id, Func<IQueryable<T>, IQueryable<T>>? include = null, CancellationToken cancellationToken = default);
/// <summary>
/// 查询所有实体
/// </summary>
/// <param name="include">查询条件表达式</param>
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
/// <returns>所有实体的集合</returns>
/// <remarks>
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
/// 注意:对于大数据量的表,建议使用分页查询
/// </remarks>
Task<IEnumerable<T>> GetAllAsync(Func<IQueryable<T>, IQueryable<T>>? include = null, CancellationToken cancellationToken = default);
/// <summary>
/// 根据条件查询实体
/// </summary>
/// <param name="predicate">查询条件表达式</param>
/// <param name="include">查询条件表达式</param>
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
/// <returns>符合条件的实体集合</returns>
/// <remarks>
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
/// 使用 LINQ 表达式树构建查询条件
/// 条件查询会被转换为 SQL 语句在数据库端执行
/// </remarks>
Task<IEnumerable<T>> FindAsync(Expression<Func<T, bool>> predicate, Func<IQueryable<T>, IQueryable<T>>? include = null, CancellationToken cancellationToken = default);
/// <summary>
/// 分页查询实体
/// </summary>
/// <param name="pageNumber">页码,从1开始</param>
/// <param name="pageSize">每页记录数</param>
/// <param name="include">查询条件表达式</param>
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
/// <returns>分页查询结果,包含总记录数和当前页数据</returns>
/// <remarks>
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
/// 分页查询可以有效减少数据传输量,提高性能
/// 建议在查询大数据量时使用
/// </remarks>
Task<(int TotalCount, IEnumerable<T> Items)> GetPagedAsync(int pageNumber, int pageSize, Func<IQueryable<T>, IQueryable<T>>? include = null, CancellationToken cancellationToken = default);
/// <summary>
/// 根据条件分页查询实体
/// </summary>
/// <param name="predicate">查询条件表达式</param>
/// <param name="pageNumber">页码,从1开始</param>
/// <param name="pageSize">每页记录数</param>
/// <param name="include">查询条件表达式</param>
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
/// <returns>分页查询结果,包含总记录数和当前页数据</returns>
/// <remarks>
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
/// 结合条件查询和分页查询,适用于大数据量的条件筛选
/// </remarks>
Task<(int TotalCount, IEnumerable<T> Items)> GetPagedAsync(
Expression<Func<T, bool>> predicate,
int pageNumber,
int pageSize,
Func<IQueryable<T>, IQueryable<T>>? include = null,
CancellationToken cancellationToken = default);
/// <summary>
/// 查询单个实体
/// </summary>
/// <param name="predicate">查询条件表达式</param>
/// <param name="include">查询条件表达式</param>
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
/// <returns>查询到的实体,如果不存在则返回 null</returns>
/// <remarks>
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
/// 如果查询结果包含多个实体,将返回第一个
/// 建议在确定只会返回一个结果时使用
/// </remarks>
Task<T?> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate, Func<IQueryable<T>, IQueryable<T>>? include = null, CancellationToken cancellationToken = default);
/// <summary>
/// 查询实体是否存在
/// </summary>
/// <param name="predicate">查询条件表达式</param>
/// <param name="include">查询条件表达式</param>
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
/// <returns>是否存在符合条件的实体</returns>
/// <remarks>
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
/// 使用 EXISTS 语句在数据库端执行,性能优于获取完整实体
/// </remarks>
Task<bool> AnyAsync(Expression<Func<T, bool>> predicate, Func<IQueryable<T>, IQueryable<T>>? include = null, CancellationToken cancellationToken = default);
/// <summary>
/// 统计符合条件的实体数量
/// </summary>
/// <param name="predicate">查询条件表达式</param>
/// <param name="include">查询条件表达式</param>
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
/// <returns>符合条件的实体数量</returns>
/// <remarks>
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
/// 使用 COUNT 语句在数据库端执行,性能优于获取完整实体
/// </remarks>
Task<int> CountAsync(Expression<Func<T, bool>> predicate, Func<IQueryable<T>, IQueryable<T>>? include = null, CancellationToken cancellationToken = default);
/// <summary>
/// 执行SQL复制查询
/// </summary>
/// <param name="sql">SQL查询语句</param>
/// <param name="parameters">SQL参数</param>
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
/// <returns>查询结果集合</returns>
/// <remarks>
/// 这是一个异步操作,用于执行自定义SQL查询
/// 支持参数化查询,防止SQL注入
/// 返回的结果会被映射到实体类型T
/// </remarks>
Task<IEnumerable<T>> ExecuteSqlQueryAsync(string sql, object[] parameters, CancellationToken cancellationToken = default);
/// <summary>
/// 执行SQL查询并映射到自定义类型
/// </summary>
/// <typeparam name="TResult">结果类型</typeparam>
/// <param name="sql">SQL查询语句</param>
/// <param name="parameters">SQL参数</param>
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
/// <returns>查询结果集合</returns>
/// <remarks>
/// 这是一个异步操作,用于执行自定义SQL查询并映射到任意类型
/// 支持参数化查询,防止SQL注入
/// 返回的结果会被映射到指定的结果类型
/// </remarks>
Task<IEnumerable<TResult>> ExecuteSqlQueryAsync<TResult>(string sql, object[] parameters, CancellationToken cancellationToken = default);
}