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
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);
|
|
}
|
|
}
|