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.

159 lines
5.8 KiB

using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;
using CellularManagement.Domain.Repositories;
using CellularManagement.Infrastructure.Context;
using Microsoft.Extensions.Logging;
using CellularManagement.Domain.Repositories.Base;
namespace CellularManagement.Infrastructure.Repositories.CQRS;
/// <summary>
/// 查询仓储实现类
/// 实现了 IQueryRepository 接口,提供数据读取操作的具体实现
/// </summary>
/// <typeparam name="T">实体类型,必须是引用类型</typeparam>
public class QueryRepository<T> : IQueryRepository<T> where T : class
{
/// <summary>
/// 数据库上下文
/// </summary>
protected readonly AppDbContext _context;
/// <summary>
/// 实体集合
/// </summary>
protected readonly DbSet<T> _dbSet;
/// <summary>
/// 日志记录器
/// </summary>
protected readonly ILogger<QueryRepository<T>> _logger;
/// <summary>
/// 构造函数
/// </summary>
public QueryRepository(
AppDbContext context,
ILogger<QueryRepository<T>> logger)
{
_context = context;
_dbSet = context.Set<T>();
_logger = logger;
}
/// <summary>
/// 根据ID查询单个实体
/// </summary>
public async Task<T?> GetByIdAsync(string id, Func<IQueryable<T>, IQueryable<T>>? include = null, CancellationToken cancellationToken = default)
{
IQueryable<T> query = _dbSet;
if (include != null)
query = include(query);
return await query.FirstOrDefaultAsync(e => EF.Property<string>(e, "Id") == id, cancellationToken);
}
/// <summary>
/// 查询所有实体
/// </summary>
public async Task<IEnumerable<T>> GetAllAsync(Func<IQueryable<T>, IQueryable<T>>? include = null, CancellationToken cancellationToken = default)
{
IQueryable<T> query = _dbSet;
if (include != null)
query = include(query);
return await query.ToListAsync(cancellationToken);
}
/// <summary>
/// 根据条件查询实体
/// </summary>
public async Task<IEnumerable<T>> FindAsync(Expression<Func<T, bool>> predicate, Func<IQueryable<T>, IQueryable<T>>? include = null, CancellationToken cancellationToken = default)
{
IQueryable<T> query = _dbSet.Where(predicate);
if (include != null)
query = include(query);
return await query.ToListAsync(cancellationToken);
}
/// <summary>
/// 分页查询实体
/// </summary>
public async Task<(int TotalCount, IEnumerable<T> Items)> GetPagedAsync(int pageNumber, int pageSize, Func<IQueryable<T>, IQueryable<T>>? include = null, CancellationToken cancellationToken = default)
{
IQueryable<T> query = _dbSet;
if (include != null)
query = include(query);
var totalCount = await query.CountAsync(cancellationToken);
var items = await query
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
.ToListAsync(cancellationToken);
return (totalCount, items);
}
/// <summary>
/// 根据条件分页查询实体
/// </summary>
public async 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)
{
IQueryable<T> query = _dbSet.Where(predicate);
if (include != null)
query = include(query);
var totalCount = await query.CountAsync(cancellationToken);
var items = await query
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
.ToListAsync(cancellationToken);
return (totalCount, items);
}
/// <summary>
/// 查询单个实体
/// </summary>
public async Task<T?> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate, Func<IQueryable<T>, IQueryable<T>>? include = null, CancellationToken cancellationToken = default)
{
IQueryable<T> query = _dbSet.Where(predicate);
if (include != null)
query = include(query);
return await query.FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
/// 查询实体是否存在
/// </summary>
public async Task<bool> AnyAsync(Expression<Func<T, bool>> predicate, Func<IQueryable<T>, IQueryable<T>>? include = null, CancellationToken cancellationToken = default)
{
IQueryable<T> query = _dbSet.Where(predicate);
if (include != null)
query = include(query);
return await query.AnyAsync(cancellationToken);
}
/// <summary>
/// 统计符合条件的实体数量
/// </summary>
public async Task<int> CountAsync(Expression<Func<T, bool>> predicate, Func<IQueryable<T>, IQueryable<T>>? include = null, CancellationToken cancellationToken = default)
{
IQueryable<T> query = _dbSet.Where(predicate);
if (include != null)
query = include(query);
return await query.CountAsync(cancellationToken);
}
/// <summary>
/// 执行SQL复制查询
/// </summary>
public async Task<IEnumerable<T>> ExecuteSqlQueryAsync(string sql, object[] parameters, CancellationToken cancellationToken = default)
{
_logger.LogInformation("执行SQL查询: {Sql}", sql);
return await _dbSet.FromSqlRaw(sql, parameters).ToListAsync(cancellationToken);
}
/// <summary>
/// 执行SQL查询并映射到自定义类型
/// </summary>
public async Task<IEnumerable<TResult>> ExecuteSqlQueryAsync<TResult>(string sql, object[] parameters, CancellationToken cancellationToken = default)
{
_logger.LogInformation("执行SQL查询并映射到类型 {ResultType}: {Sql}", typeof(TResult).Name, sql);
return await _context.Database.SqlQueryRaw<TResult>(sql, parameters).ToListAsync(cancellationToken);
}
}