From 75e458e48c64670f2133d1397106bd491b1ae765 Mon Sep 17 00:00:00 2001 From: muhammedaltug Date: Mon, 21 Dec 2020 15:07:30 +0300 Subject: [PATCH 1/4] source code link added to post --- .../POST.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/en/Community-Articles/2020-12-11-Using-Angular-Material-Components-With-ABP-Framework/POST.md b/docs/en/Community-Articles/2020-12-11-Using-Angular-Material-Components-With-ABP-Framework/POST.md index 7b1ae846af..02cef11a2e 100644 --- a/docs/en/Community-Articles/2020-12-11-Using-Angular-Material-Components-With-ABP-Framework/POST.md +++ b/docs/en/Community-Articles/2020-12-11-Using-Angular-Material-Components-With-ABP-Framework/POST.md @@ -260,7 +260,7 @@ import { MatFormFieldModule } from "@angular/material/form-field"; import { MatInputModule } from "@angular/material/input"; import { MatSelectModule } from "@angular/material/select"; import { MatIconModule } from "@angular/material/icon"; -import { MatNativeDateModule } from '@angular/material/core'; +import { MatNativeDateModule } from "@angular/material/core"; @NgModule({ imports: [ @@ -1576,6 +1576,10 @@ Final UI looks as shown below: ![Author With Books](./author-with-books.gif) +## The Source Code + +You can download the source code from [here](https://github.com/abpframework/abp-samples/tree/master/AcmeBookStoreAngularMaterial). + ## Conclusion We implemented Angular Material Components to our angular application which was created with ABP Framework. There is no blocker case of using angular libraries with the ABP framework. From b4e9b7aac22320797169f465118aa78658b61d58 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 4 Jan 2021 13:34:40 +0800 Subject: [PATCH 2/4] Make FeatureManagementProvider's NormalizeProviderKey method async. --- .../EditionFeatureManagementProvider.cs | 13 +++++++------ .../FeatureManagement/FeatureManagementProvider.cs | 10 +++++----- .../TenantFeatureManagementProvider.cs | 11 ++++++----- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/EditionFeatureManagementProvider.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/EditionFeatureManagementProvider.cs index d904ef124a..0106e56af2 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/EditionFeatureManagementProvider.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/EditionFeatureManagementProvider.cs @@ -1,4 +1,5 @@ using System.Security.Principal; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.Features; using Volo.Abp.Security.Claims; @@ -12,21 +13,21 @@ namespace Volo.Abp.FeatureManagement protected ICurrentPrincipalAccessor PrincipalAccessor { get; } public EditionFeatureManagementProvider( - IFeatureManagementStore store, - ICurrentPrincipalAccessor principalAccessor) + IFeatureManagementStore store, + ICurrentPrincipalAccessor principalAccessor) : base(store) { PrincipalAccessor = principalAccessor; } - protected override string NormalizeProviderKey(string providerKey) + protected override Task NormalizeProviderKeyAsync(string providerKey) { if (providerKey != null) { - return providerKey; + return Task.FromResult(providerKey); } - return PrincipalAccessor.Principal?.FindEditionId()?.ToString("N"); + return Task.FromResult(PrincipalAccessor.Principal?.FindEditionId()?.ToString("N")); } } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManagementProvider.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManagementProvider.cs index 45e5f65b4c..42b275c01b 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManagementProvider.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureManagementProvider.cs @@ -21,22 +21,22 @@ namespace Volo.Abp.FeatureManagement public virtual async Task GetOrNullAsync(FeatureDefinition feature, string providerKey) { - return await Store.GetOrNullAsync(feature.Name, Name, NormalizeProviderKey(providerKey)); + return await Store.GetOrNullAsync(feature.Name, Name, await NormalizeProviderKeyAsync(providerKey)); } public virtual async Task SetAsync(FeatureDefinition feature, string value, string providerKey) { - await Store.SetAsync(feature.Name, value, Name, NormalizeProviderKey(providerKey)); + await Store.SetAsync(feature.Name, value, Name, await NormalizeProviderKeyAsync(providerKey)); } public virtual async Task ClearAsync(FeatureDefinition feature, string providerKey) { - await Store.DeleteAsync(feature.Name, Name, NormalizeProviderKey(providerKey)); + await Store.DeleteAsync(feature.Name, Name, await NormalizeProviderKeyAsync(providerKey)); } - protected virtual string NormalizeProviderKey(string providerKey) + protected virtual Task NormalizeProviderKeyAsync(string providerKey) { - return providerKey; + return Task.FromResult(providerKey); } } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/TenantFeatureManagementProvider.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/TenantFeatureManagementProvider.cs index 91302580d2..4e822fd7e0 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/TenantFeatureManagementProvider.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/TenantFeatureManagementProvider.cs @@ -1,4 +1,5 @@ -using Volo.Abp.DependencyInjection; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; using Volo.Abp.Features; using Volo.Abp.MultiTenancy; @@ -18,14 +19,14 @@ namespace Volo.Abp.FeatureManagement CurrentTenant = currentTenant; } - protected override string NormalizeProviderKey(string providerKey) + protected override Task NormalizeProviderKeyAsync(string providerKey) { if (providerKey != null) { - return providerKey; + return Task.FromResult(providerKey); } - return CurrentTenant.Id?.ToString(); + return Task.FromResult(CurrentTenant.Id?.ToString()); } } -} \ No newline at end of file +} From eaaa8b4acef83e2d0d1927a030b1ec6cf2d39a57 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 4 Jan 2021 17:01:19 +0800 Subject: [PATCH 3/4] Always use Repository.GetQueryableAsync() in the method of RepositoryAsyncExtensions class --- .../Repositories/RepositoryAsyncExtensions.cs | 215 +++++++++++------- 1 file changed, 129 insertions(+), 86 deletions(-) diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryAsyncExtensions.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryAsyncExtensions.cs index acc1c3a1bd..87f119016d 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryAsyncExtensions.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryAsyncExtensions.cs @@ -26,415 +26,458 @@ namespace Volo.Abp.Domain.Repositories #region Any/All - public static Task AnyAsync( + public static async Task AnyAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AnyAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AnyAsync(queryable, predicate, cancellationToken); } - public static Task AllAsync( + public static async Task AllAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AllAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AllAsync(queryable, predicate, cancellationToken); } #endregion #region Count/LongCount - public static Task CountAsync( + public static async Task CountAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.CountAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.CountAsync(queryable, cancellationToken); } - public static Task CountAsync( + public static async Task CountAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.CountAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.CountAsync(queryable, predicate, cancellationToken); } - public static Task LongCountAsync( + public static async Task LongCountAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.LongCountAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.LongCountAsync(queryable, cancellationToken); } - public static Task LongCountAsync( + public static async Task LongCountAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.LongCountAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.LongCountAsync(queryable, predicate, cancellationToken); } #endregion #region First/FirstOrDefault - public static Task FirstAsync( + public static async Task FirstAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.FirstAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.FirstAsync(queryable, cancellationToken); } - public static Task FirstAsync( + public static async Task FirstAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.FirstAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.FirstAsync(queryable, predicate, cancellationToken); } - public static Task FirstOrDefaultAsync( + public static async Task FirstOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.FirstOrDefaultAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.FirstOrDefaultAsync(queryable, cancellationToken); } - public static Task FirstOrDefaultAsync( + public static async Task FirstOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.FirstOrDefaultAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.FirstOrDefaultAsync(queryable, predicate, cancellationToken); } #endregion #region Last/LastOrDefault - public static Task LastAsync( + public static async Task LastAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.LastAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.LastAsync(queryable, cancellationToken); } - public static Task LastAsync( + public static async Task LastAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.LastAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.LastAsync(queryable, predicate, cancellationToken); } - public static Task LastOrDefaultAsync( + public static async Task LastOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.LastOrDefaultAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.LastOrDefaultAsync(queryable, cancellationToken); } - public static Task LastOrDefaultAsync( + public static async Task LastOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.LastOrDefaultAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.LastOrDefaultAsync(queryable, predicate, cancellationToken); } #endregion #region Single/SingleOrDefault - public static Task SingleAsync( + public static async Task SingleAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SingleAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SingleAsync(queryable, cancellationToken); } - public static Task SingleAsync( + public static async Task SingleAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SingleAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SingleAsync(queryable, predicate, cancellationToken); } - public static Task SingleOrDefaultAsync( + public static async Task SingleOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SingleOrDefaultAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SingleOrDefaultAsync(queryable, cancellationToken); } - public static Task SingleOrDefaultAsync( + public static async Task SingleOrDefaultAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> predicate, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SingleOrDefaultAsync(repository, predicate, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SingleOrDefaultAsync(queryable, predicate, cancellationToken); } #endregion #region Min - public static Task MinAsync( + public static async Task MinAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.MinAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.MinAsync(queryable, cancellationToken); } - public static Task MinAsync( + public static async Task MinAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.MinAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.MinAsync(queryable, selector, cancellationToken); } #endregion #region Max - public static Task MaxAsync( + public static async Task MaxAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.MaxAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.MaxAsync(queryable, cancellationToken); } - public static Task MaxAsync( + public static async Task MaxAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.MaxAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.MaxAsync(queryable, selector, cancellationToken); } #endregion #region Sum - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } - public static Task SumAsync( + public static async Task SumAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.SumAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.SumAsync(queryable, selector, cancellationToken); } #endregion #region Average - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } - public static Task AverageAsync( + public static async Task AverageAsync( [NotNull] this IReadOnlyRepository repository, [NotNull] Expression> selector, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.AverageAsync(repository, selector, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.AverageAsync(queryable, selector, cancellationToken); } #endregion #region ToList/Array - public static Task> ToListAsync( + public static async Task> ToListAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.ToListAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.ToListAsync(queryable, cancellationToken); } - public static Task ToArrayAsync( + public static async Task ToArrayAsync( [NotNull] this IReadOnlyRepository repository, CancellationToken cancellationToken = default) where T : class, IEntity { - return repository.AsyncExecuter.ToArrayAsync(repository, cancellationToken); + var queryable = await repository.GetQueryableAsync(); + return await repository.AsyncExecuter.ToArrayAsync(queryable, cancellationToken); } #endregion From 28d1690b14385b7408e962b5758e886de788bccc Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 5 Jan 2021 13:30:56 +0800 Subject: [PATCH 4/4] Add hard delete by predicate for IRepository. Resolve #6925 --- .../Repositories/RepositoryExtensions.cs | 67 ++++++++++++++++++- .../Abp/TestApp/Testing/HardDelete_Tests.cs | 58 +++++++++++++++- 2 files changed, 120 insertions(+), 5 deletions(-) diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs index ef44d6830d..168fe2b0c0 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryExtensions.cs @@ -1,8 +1,11 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Data; using Volo.Abp.Domain.Entities; using Volo.Abp.DynamicProxy; using Volo.Abp.Uow; @@ -43,6 +46,65 @@ namespace Volo.Abp.Domain.Repositories } } + public static async Task HardDeleteAsync( + this IRepository repository, + Expression> predicate, + bool autoSave = false, + CancellationToken cancellationToken = default + ) + where TEntity : class, IEntity, ISoftDelete + { + if (!(ProxyHelper.UnProxy(repository) is IUnitOfWorkManagerAccessor unitOfWorkManagerAccessor)) + { + throw new AbpException($"The given repository (of type {repository.GetType().AssemblyQualifiedName}) should implement the {typeof(IUnitOfWorkManagerAccessor).AssemblyQualifiedName} interface in order to invoke the {nameof(HardDeleteAsync)} method!"); + } + + var uowManager = unitOfWorkManagerAccessor.UnitOfWorkManager; + if (uowManager == null) + { + throw new AbpException($"{nameof(unitOfWorkManagerAccessor.UnitOfWorkManager)} property of the given {nameof(repository)} object is null!"); + } + + if (uowManager.Current == null) + { + using (var uow = uowManager.Begin()) + { + await HardDeleteWithUnitOfWorkAsync(repository, predicate, autoSave, cancellationToken, uowManager.Current); + await uow.CompleteAsync(cancellationToken); + } + } + else + { + await HardDeleteWithUnitOfWorkAsync(repository, predicate, autoSave, cancellationToken, uowManager.Current); + } + } + + private static async Task HardDeleteWithUnitOfWorkAsync( + IRepository repository, + Expression> predicate, + bool autoSave, + CancellationToken cancellationToken, IUnitOfWork currentUow + ) + where TEntity : class, IEntity, ISoftDelete + { + var hardDeleteEntities = (HashSet) currentUow.Items.GetOrAdd( + UnitOfWorkItemNames.HardDeletedEntities, + () => new HashSet() + ); + + List entities; + using (currentUow.ServiceProvider.GetRequiredService>().Disable()) + { + entities = await repository.AsyncExecuter.ToListAsync((await repository.GetQueryableAsync()).Where(predicate), cancellationToken); + } + + foreach (var entity in entities) + { + hardDeleteEntities.Add(entity); + await repository.DeleteAsync(entity, autoSave, cancellationToken); + } + } + public static async Task HardDeleteAsync( this IBasicRepository repository, TEntity entity, @@ -77,8 +139,8 @@ namespace Volo.Abp.Domain.Repositories } private static async Task HardDeleteWithUnitOfWorkAsync( - IBasicRepository repository, - TEntity entity, + IBasicRepository repository, + TEntity entity, bool autoSave, CancellationToken cancellationToken, IUnitOfWork currentUow ) @@ -90,7 +152,6 @@ namespace Volo.Abp.Domain.Repositories ); hardDeleteEntities.Add(entity); - await repository.DeleteAsync(entity, autoSave, cancellationToken); } } diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HardDelete_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HardDelete_Tests.cs index 1eac79fd7c..3d9b324da8 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HardDelete_Tests.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/HardDelete_Tests.cs @@ -30,8 +30,26 @@ namespace Volo.Abp.TestApp.Testing var douglas = await PersonRepository.GetAsync(TestDataBuilder.UserDouglasId); await PersonRepository.HardDeleteAsync(douglas); - douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); - douglas.ShouldBeNull(); + using (DataFilter.Disable()) + { + douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); + douglas.ShouldBeNull(); + } + } + + [Fact] + public async Task Should_HardDelete_Entities_With_Predicate() + { + await PersonRepository.HardDeleteAsync(x => x.Id == TestDataBuilder.UserDouglasId || x.Id == TestDataBuilder.UserJohnDeletedId); + + using (DataFilter.Disable()) + { + var douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); + douglas.ShouldBeNull(); + + var john = await PersonRepository.FindAsync(TestDataBuilder.UserJohnDeletedId); + john.ShouldBeNull(); + } } [Fact] @@ -62,8 +80,44 @@ namespace Volo.Abp.TestApp.Testing await uow.CompleteAsync(); } + using (DataFilter.Disable()) + { + douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); + douglas.ShouldBeNull(); + } + } + + [Fact] + public async Task Should_HardDelete_Soft_Deleted_Entities_With_Predicate() + { + var douglas = await PersonRepository.GetAsync(TestDataBuilder.UserDouglasId); + await PersonRepository.DeleteAsync(douglas); + douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); douglas.ShouldBeNull(); + + using (DataFilter.Disable()) + { + douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); + douglas.ShouldNotBeNull(); + douglas.IsDeleted.ShouldBeTrue(); + douglas.DeletionTime.ShouldNotBeNull(); + } + + using (var uow = UnitOfWorkManager.Begin()) + { + await PersonRepository.HardDeleteAsync(x => x.Id == TestDataBuilder.UserDouglasId || x.Id == TestDataBuilder.UserJohnDeletedId); + await uow.CompleteAsync(); + } + + using (DataFilter.Disable()) + { + douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); + douglas.ShouldBeNull(); + + var john = await PersonRepository.FindAsync(TestDataBuilder.UserJohnDeletedId); + john.ShouldBeNull(); + } } } }