using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; using Abp.Collections.Extensions; using Abp.Dependency; using Abp.Domain.Entities; using Abp.Domain.Uow; using Abp.Reflection; using Abp.Runtime.Session; using Abp.Threading; namespace Abp.Domain.Repositories { public static class RepositoryExtensions { public static async Task EnsureCollectionLoadedAsync( this IRepository repository, TEntity entity, Expression>> collectionExpression, CancellationToken cancellationToken = default(CancellationToken) ) where TEntity : class, IEntity where TProperty : class { var repo = ProxyHelper.UnProxy(repository) as ISupportsExplicitLoading; if (repo != null) { await repo.EnsureCollectionLoadedAsync(entity, collectionExpression, cancellationToken); } } public static void EnsureCollectionLoaded( this IRepository repository, TEntity entity, Expression>> collectionExpression ) where TEntity : class, IEntity where TProperty : class { AsyncHelper.RunSync(() => repository.EnsureCollectionLoadedAsync(entity, collectionExpression)); } public static async Task EnsurePropertyLoadedAsync( this IRepository repository, TEntity entity, Expression> propertyExpression, CancellationToken cancellationToken = default(CancellationToken) ) where TEntity : class, IEntity where TProperty : class { var repo = ProxyHelper.UnProxy(repository) as ISupportsExplicitLoading; if (repo != null) { await repo.EnsurePropertyLoadedAsync(entity, propertyExpression, cancellationToken); } } public static void EnsurePropertyLoaded( this IRepository repository, TEntity entity, Expression> propertyExpression ) where TEntity : class, IEntity where TProperty : class { AsyncHelper.RunSync(() => repository.EnsurePropertyLoadedAsync(entity, propertyExpression)); } public static IIocResolver GetIocResolver(this IRepository repository) where TEntity : class, IEntity { var repo = ProxyHelper.UnProxy(repository) as AbpRepositoryBase; if (repo != null) { return repo.IocResolver; } throw new ArgumentException($"Given {nameof(repository)} is not inherited from {typeof(AbpRepositoryBase).AssemblyQualifiedName}"); } public static async Task HardDeleteAsync(this IRepository repository, TEntity entity) where TEntity : class, IEntity, ISoftDelete { var repo = ProxyHelper.UnProxy(repository) as IRepository; if (repo == null) { throw new ArgumentException($"Given {nameof(repository)} is not inherited from {typeof(IRepository).AssemblyQualifiedName}"); } var items = ((IUnitOfWorkManagerAccessor)repo).UnitOfWorkManager.Current.Items; var hardDeleteEntities = items.GetOrAdd(UnitOfWorkExtensionDataTypes.HardDelete, () => new HashSet()) as HashSet; var tenantId = GetCurrentTenantIdOrNull(repo.GetIocResolver()); var hardDeleteKey = EntityHelper.GetHardDeleteKey(entity, tenantId); hardDeleteEntities.Add(hardDeleteKey); await repo.DeleteAsync(entity); } public static void HardDelete(this IRepository repository, TEntity entity) where TEntity : class, IEntity, ISoftDelete { var repo = ProxyHelper.UnProxy(repository) as IRepository; if (repo == null) { throw new ArgumentException($"Given {nameof(repository)} is not inherited from {typeof(IRepository).AssemblyQualifiedName}"); } var items = ((IUnitOfWorkManagerAccessor)repo).UnitOfWorkManager.Current.Items; var hardDeleteEntities = items.GetOrAdd(UnitOfWorkExtensionDataTypes.HardDelete, () => new HashSet()) as HashSet; var tenantId = GetCurrentTenantIdOrNull(repo.GetIocResolver()); var hardDeleteKey = EntityHelper.GetHardDeleteKey(entity, tenantId); hardDeleteEntities.Add(hardDeleteKey); repo.Delete(entity); } public static async Task HardDeleteAsync(this IRepository repository, Expression> predicate) where TEntity : class, IEntity, ISoftDelete { foreach (var entity in repository.GetAll().Where(predicate).ToList()) { await repository.HardDeleteAsync(entity); } } public static void HardDelete(this IRepository repository, Expression> predicate) where TEntity : class, IEntity, ISoftDelete { foreach (var entity in repository.GetAll().Where(predicate).ToList()) { repository.HardDelete(entity); } } private static int? GetCurrentTenantIdOrNull(IIocResolver iocResolver) { using (var scope = iocResolver.CreateScope()) { var currentUnitOfWorkProvider = scope.Resolve(); if (currentUnitOfWorkProvider?.Current != null) { return currentUnitOfWorkProvider.Current.GetTenantId(); } } return iocResolver.Resolve().TenantId; } } }