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.
234 lines
7.0 KiB
234 lines
7.0 KiB
using Microsoft.EntityFrameworkCore;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using TaskManager.Entity;
|
|
using TaskManager.EntityFramework;
|
|
using Wood.Util;
|
|
|
|
namespace TaskManager.EntityFramework.Repository
|
|
{
|
|
|
|
|
|
|
|
|
|
public class Repository<TEntity> : IRepository<TEntity>
|
|
where TEntity : BaseEntity
|
|
{
|
|
private readonly DbContext _context;
|
|
private readonly DbSet<TEntity> _dbSet;
|
|
|
|
public Repository(DbContext context)
|
|
{
|
|
_context = context;
|
|
_dbSet = context.Set<TEntity>();
|
|
}
|
|
|
|
public async Task<TEntity> GetByIdAsync(int id)
|
|
{
|
|
return await _dbSet.FindAsync(id);
|
|
}
|
|
|
|
public async Task<IEnumerable<TEntity>> GetAllAsync()
|
|
{
|
|
return await _dbSet.ToListAsync();
|
|
}
|
|
|
|
public async Task<TEntity> AddAsync(TEntity entity)
|
|
{
|
|
entity.CreationTime = DateTime.UtcNow;
|
|
await _dbSet.AddAsync(entity);
|
|
await _context.SaveChangesAsync();
|
|
return entity;
|
|
}
|
|
|
|
public async Task UpdateAsync(TEntity entity)
|
|
{
|
|
|
|
_dbSet.Update(entity);
|
|
await _context.SaveChangesAsync();
|
|
}
|
|
|
|
public async Task DeleteAsync(int id)
|
|
{
|
|
var entity = await _dbSet.FindAsync(id);
|
|
if (entity != null)
|
|
{
|
|
_dbSet.Remove(entity);
|
|
await _context.SaveChangesAsync();
|
|
}
|
|
}
|
|
|
|
public async Task<PagedResult<TEntity>> GetPagedAsync(PagingParams pagingParams)
|
|
{
|
|
return await _dbSet.AsNoTracking().ToPagedListAsync(pagingParams);
|
|
}
|
|
|
|
|
|
public async Task<PagedResult<TEntity>> GetPagedAsync(
|
|
Expression<Func<TEntity, bool>> filter = null,
|
|
PagingParams pagingParams = null)
|
|
{
|
|
IQueryable<TEntity> query = _dbSet.AsNoTracking();
|
|
|
|
// 应用过滤条件
|
|
if (filter != null)
|
|
{
|
|
query = query.Where(filter);
|
|
}
|
|
|
|
// 应用动态过滤
|
|
if (pagingParams?.Filters != null && pagingParams.Filters.Any())
|
|
{
|
|
query = query.ApplyFilters(pagingParams.Filters);
|
|
}
|
|
|
|
// 应用分页和排序
|
|
pagingParams ??= new PagingParams();
|
|
return await query.ToPagedListAsync(pagingParams);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
public class PagedResult<T>
|
|
{
|
|
public List<T> Data { get; set; }
|
|
public int TotalCount { get; set; }
|
|
public int PageNumber { get; set; }
|
|
public int PageSize { get; set; }
|
|
public int TotalPages => (int)Math.Ceiling(TotalCount / (double)PageSize);
|
|
|
|
public PagedResult()
|
|
{
|
|
Data = new List<T>();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public class PagingParams
|
|
{
|
|
private const int MaxPageSize = 50;
|
|
private int _pageSize = 10;
|
|
|
|
public int PageNumber { get; set; } = 1;
|
|
public int PageSize
|
|
{
|
|
get => _pageSize;
|
|
set => _pageSize = (value > MaxPageSize) ? MaxPageSize : value;
|
|
}
|
|
public string SortBy { get; set; }
|
|
public bool IsAscending { get; set; } = true;
|
|
|
|
// 新增:过滤条件(键值对)
|
|
public Dictionary<string, string> Filters { get; set; } = new();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static class QueryableExtensions
|
|
{
|
|
public static IQueryable<T> ApplySort<T>(this IQueryable<T> query, string sortBy, bool isAscending)
|
|
{
|
|
if (string.IsNullOrEmpty(sortBy)) return query;
|
|
|
|
var parameter = Expression.Parameter(typeof(T), "x");
|
|
var property = Expression.Property(parameter, sortBy);
|
|
var lambda = Expression.Lambda(property, parameter);
|
|
|
|
var methodName = isAscending ? "OrderBy" : "OrderByDescending";
|
|
var resultExpression = Expression.Call(
|
|
typeof(Queryable),
|
|
methodName,
|
|
new[] { typeof(T), property.Type },
|
|
query.Expression,
|
|
Expression.Quote(lambda));
|
|
|
|
return query.Provider.CreateQuery<T>(resultExpression);
|
|
}
|
|
|
|
|
|
public static IQueryable<T> ApplyFilters<T>(this IQueryable<T> query, Dictionary<string, string> filters)
|
|
{
|
|
if (filters == null || !filters.Any()) return query;
|
|
|
|
foreach (var filter in filters)
|
|
{
|
|
var property = typeof(T).GetProperty(filter.Key,
|
|
BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
|
|
|
|
if (property != null)
|
|
{
|
|
var parameter = Expression.Parameter(typeof(T), "x");
|
|
var propertyAccess = Expression.Property(parameter, property);
|
|
var constant = Expression.Constant(
|
|
Convert.ChangeType(filter.Value, property.PropertyType));
|
|
|
|
var equalExpression = Expression.Equal(propertyAccess, constant);
|
|
var lambda = Expression.Lambda<Func<T, bool>>(equalExpression, parameter);
|
|
|
|
query = query.Where(lambda);
|
|
}
|
|
}
|
|
|
|
return query;
|
|
}
|
|
|
|
|
|
|
|
public static IQueryable<T> ApplyStringFilter<T>(this IQueryable<T> query,
|
|
string propertyName, string value)
|
|
{
|
|
var property = typeof(T).GetProperty(propertyName,
|
|
BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
|
|
|
|
if (property != null && property.PropertyType == typeof(string) && !string.IsNullOrEmpty(value))
|
|
{
|
|
var parameter = Expression.Parameter(typeof(T), "x");
|
|
var propertyAccess = Expression.Property(parameter, property);
|
|
var containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
|
|
var constant = Expression.Constant(value);
|
|
|
|
var containsExpression = Expression.Call(propertyAccess, containsMethod, constant);
|
|
var lambda = Expression.Lambda<Func<T, bool>>(containsExpression, parameter);
|
|
|
|
query = query.Where(lambda);
|
|
}
|
|
|
|
return query;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static async Task<PagedResult<T>> ToPagedListAsync<T>(this IQueryable<T> source, PagingParams pagingParams)
|
|
{
|
|
var count = await source.CountAsync();
|
|
var items = await source
|
|
.ApplySort(pagingParams.SortBy, pagingParams.IsAscending)
|
|
.Skip((pagingParams.PageNumber - 1) * pagingParams.PageSize)
|
|
.Take(pagingParams.PageSize)
|
|
.ToListAsync();
|
|
|
|
return new PagedResult<T>
|
|
{
|
|
Data = items,
|
|
TotalCount = count,
|
|
PageNumber = pagingParams.PageNumber,
|
|
PageSize = pagingParams.PageSize
|
|
};
|
|
}
|
|
}
|
|
|
|
}
|
|
|