using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using VCommon.VEntity; namespace VCommon.VEntityFrameworkCore { public abstract class VEfRepositoryBase : IDisposable where TEntity : VEntityBase where TDbContext : VEfDbContextBase { private TDbContext _dbContext; public TDbContext DbContext { get => _dbContext ??= ResolveDbContextInstance(); set => _dbContext = value; } private readonly Dictionary _filterState = new() { { VEfDataFilters.SoftDelete, true }, { VEfDataFilters.Passive, true }, }; protected virtual IQueryable ProcessFilters(IQueryable input) { if (_filterState[VEfDataFilters.SoftDelete] && typeof(TEntity).IsAssignableTo(typeof(ISoftDelete))) { input = input.Where(p => ((ISoftDelete)p).IsAbolish == false); } if (_filterState[VEfDataFilters.Passive] && typeof(TEntity).IsAssignableTo(typeof(IPassive))) { input = input.Where(p => ((IPassive)p).IsEnable); } return input; } public abstract VEfRepositoryBase ForkRepository() where TForkEntity : VEntityBase; protected abstract TDbContext ResolveDbContextInstance(); protected DbSet DbSet => DbContext.Set(); public virtual void DisableFilter(string filterName) => _filterState[filterName] = false; public virtual void EnableFilter(string filterName) => _filterState[filterName] = true; public virtual bool IsFilterEnabled(string filterName) => _filterState[filterName]; public virtual int Count(Expression> queryExpression = null) { var source = ProcessFilters(DbSet.AsNoTracking()); return queryExpression != null ? source.Count(queryExpression) : source.Count(); } public virtual IQueryable QueryNoTracking(Expression> queryExpression = null) { var source = ProcessFilters(DbSet.AsNoTracking()); return queryExpression != null ? source.Where(queryExpression) : source; } public virtual IQueryable Query(Expression> queryExpression = null) { var source = ProcessFilters(DbSet); return null == queryExpression ? source : source.Where(queryExpression); } public virtual void Delete(TEntity entity) => DbSet.Remove(entity); public virtual TEntity Add(TEntity entity) => DbSet.Add(entity).Entity; public bool CheckExist(Expression> expression = null) { var source = ProcessFilters(DbSet); return null == expression ? source.Any() : source.Any(expression); } public virtual TEntity GetEntityOrDefault(Guid id) => ProcessFilters(DbSet).FirstOrDefault(p => p.Id == id); public virtual TEntity GetEntityOrDefault(Expression> expression = null) { var source = ProcessFilters(DbSet); return null == expression ? source.FirstOrDefault() : source.FirstOrDefault(expression); } public int SaveChanges() => DbContext.SaveChanges(); public void Dispose() => DbContext?.Dispose(); } }