using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; using Volo.Abp.Data; using Volo.Abp.Domain.Entities; using Volo.Abp.MultiTenancy; namespace Volo.Abp.Domain.Repositories { public abstract class QueryableRepositoryBase : RepositoryBase, IQueryableRepository where TEntity : class, IEntity { public IDataFilter DataFilter { get; set; } public ICurrentTenant CurrentTenant { get; set; } public virtual Type ElementType => GetQueryable().ElementType; public virtual Expression Expression => GetQueryable().Expression; public virtual IQueryProvider Provider => GetQueryable().Provider; IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public IEnumerator GetEnumerator() { return GetQueryable().GetEnumerator(); } protected abstract IQueryable GetQueryable(); public virtual void Delete(Expression> predicate) { foreach (var entity in GetQueryable().Where(predicate).ToList()) { Delete(entity); } } public virtual Task DeleteAsync(Expression> predicate, CancellationToken cancellationToken = default) { Delete(predicate); return Task.CompletedTask; } //TODO: Is that needed..? protected virtual IQueryable ApplyDataFilters(IQueryable query) { if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) { query = query.WhereIf(DataFilter.IsEnabled(), e => ((ISoftDelete)e).IsDeleted == false); } if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity))) { var tenantId = CurrentTenant.Id; query = query.WhereIf(DataFilter.IsEnabled(), e => ((IMultiTenant)e).TenantId == tenantId); } return query; } } public abstract class QueryableRepositoryBase : QueryableRepositoryBase, IQueryableRepository where TEntity : class, IEntity { public virtual TEntity Find(TKey id) { return GetQueryable().FirstOrDefault(EntityHelper.CreateEqualityExpressionForId(id)); } public virtual TEntity Get(TKey id) { var entity = Find(id); if (entity == null) { throw new EntityNotFoundException(typeof(TEntity), id); } return entity; } public virtual Task GetAsync(TKey id, CancellationToken cancellationToken = default) { return Task.FromResult(Get(id)); } public virtual Task FindAsync(TKey id, CancellationToken cancellationToken = default) { return Task.FromResult(Find(id)); } public virtual void Delete(TKey id) { var entity = Find(id); if (entity == null) { return; } Delete(entity); } public virtual Task DeleteAsync(TKey id, CancellationToken cancellationToken = default) { Delete(id); return Task.CompletedTask; } } }