From 9355e0673df9fc5f0e456d08435889d65d9891e9 Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 10 May 2022 11:19:09 +0800 Subject: [PATCH] Add document and unit tests. --- docs/en/Entity-Framework-Core.md | 12 ++++++ .../Repositories/RepositoryExtensions.cs | 20 +++++----- .../RepositoryExtensions_Tests.cs | 8 ++++ .../RepositoryExtensions_Tests.cs | 8 ++++ .../RepositoryExtensions_Tests.cs | 10 +++++ .../Testing/RepositoryExtensions_Tests.cs | 38 +++++++++++++++++++ 6 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Repositories/RepositoryExtensions_Tests.cs create mode 100644 framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/Repositories/RepositoryExtensions_Tests.cs create mode 100644 framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/RepositoryExtensions_Tests.cs create mode 100644 framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/RepositoryExtensions_Tests.cs diff --git a/docs/en/Entity-Framework-Core.md b/docs/en/Entity-Framework-Core.md index 568623a15d..de26b7c3f0 100644 --- a/docs/en/Entity-Framework-Core.md +++ b/docs/en/Entity-Framework-Core.md @@ -607,6 +607,18 @@ Whenever you access to a property/collection, EF Core automatically performs an See also [lazy loading document](https://docs.microsoft.com/en-us/ef/core/querying/related-data/lazy) of the EF Core. +## Repository Extensions + +There are some useful repository extension methods. + +````csharp +EnsureCollectionLoadedAsync // **Explicitly load** a sub collection. +EnsurePropertyLoadedAsync // **Explicitly load** a navigation property. +EnsureExistsAsync // Make sure the entitys exists, It accepts the entity id or a query expression. +HardDeleteAsync // Hard delete the entitys, It accepts one or more entities or query expressions. +HardDeleteWithUnitOfWorkAsync // Hard delete the entitys in a uow(create a new uow if current is null), It accepts one or more entities or query expressions. +```` + ## Access to the EF Core API In most cases, you want to hide EF Core APIs behind a repository (this is the main purpose of the repository pattern). However, if you want to access the `DbContext` instance over the repository, you can use `GetDbContext()` or `GetDbSet()` extension methods. Example: 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 21162ed9e7..379203f46a 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 @@ -15,7 +15,7 @@ namespace Volo.Abp.Domain.Repositories; public static class RepositoryExtensions { - public static async Task EnsureCollectionLoadedAsync( + public async static Task EnsureCollectionLoadedAsync( this IBasicRepository repository, TEntity entity, Expression>> propertyExpression, @@ -31,7 +31,7 @@ public static class RepositoryExtensions } } - public static async Task EnsurePropertyLoadedAsync( + public async static Task EnsurePropertyLoadedAsync( this IBasicRepository repository, TEntity entity, Expression> propertyExpression, @@ -47,7 +47,7 @@ public static class RepositoryExtensions } } - public static async Task EnsureExistsAsync( + public async static Task EnsureExistsAsync( this IRepository repository, TKey id, CancellationToken cancellationToken = default @@ -60,7 +60,7 @@ public static class RepositoryExtensions } } - public static async Task EnsureExistsAsync( + public async static Task EnsureExistsAsync( this IRepository repository, Expression> expression, CancellationToken cancellationToken = default @@ -73,7 +73,7 @@ public static class RepositoryExtensions } } - public static async Task HardDeleteAsync( + public async static Task HardDeleteAsync( this IRepository repository, Expression> predicate, bool autoSave = false, @@ -97,7 +97,7 @@ public static class RepositoryExtensions } } - public static async Task HardDeleteAsync( + public async static Task HardDeleteAsync( this IBasicRepository repository, IEnumerable entities, bool autoSave = false, @@ -121,7 +121,7 @@ public static class RepositoryExtensions } } - public static async Task HardDeleteAsync( + public async static Task HardDeleteAsync( this IBasicRepository repository, TEntity entity, bool autoSave = false, @@ -165,7 +165,7 @@ public static class RepositoryExtensions return unitOfWorkManagerAccessor.UnitOfWorkManager; } - private static async Task HardDeleteWithUnitOfWorkAsync( + private async static Task HardDeleteWithUnitOfWorkAsync( IRepository repository, Expression> predicate, bool autoSave, @@ -181,7 +181,7 @@ public static class RepositoryExtensions } } - private static async Task HardDeleteWithUnitOfWorkAsync( + private async static Task HardDeleteWithUnitOfWorkAsync( IBasicRepository repository, IEnumerable entities, bool autoSave, @@ -199,7 +199,7 @@ public static class RepositoryExtensions await repository.DeleteManyAsync(entities, autoSave, cancellationToken); } - private static async Task HardDeleteWithUnitOfWorkAsync( + private async static Task HardDeleteWithUnitOfWorkAsync( IBasicRepository repository, TEntity entity, bool autoSave, diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Repositories/RepositoryExtensions_Tests.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Repositories/RepositoryExtensions_Tests.cs new file mode 100644 index 0000000000..70f99ac26a --- /dev/null +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Repositories/RepositoryExtensions_Tests.cs @@ -0,0 +1,8 @@ +using Volo.Abp.TestApp.Testing; + +namespace Volo.Abp.EntityFrameworkCore.Repositories; + +public class RepositoryExtensions_Tests : RepositoryExtensions_Tests +{ + +} diff --git a/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/Repositories/RepositoryExtensions_Tests.cs b/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/Repositories/RepositoryExtensions_Tests.cs new file mode 100644 index 0000000000..dbb37bb71e --- /dev/null +++ b/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/Repositories/RepositoryExtensions_Tests.cs @@ -0,0 +1,8 @@ +using Volo.Abp.TestApp.Testing; + +namespace Volo.Abp.MemoryDb.Repositories; + +public class RepositoryExtensions_Tests : RepositoryExtensions_Tests +{ + +} diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/RepositoryExtensions_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/RepositoryExtensions_Tests.cs new file mode 100644 index 0000000000..dd653878b8 --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/RepositoryExtensions_Tests.cs @@ -0,0 +1,10 @@ +using Volo.Abp.TestApp.Testing; +using Xunit; + +namespace Volo.Abp.MongoDB.Repositories; + +[Collection(MongoTestCollection.Name)] +public class RepositoryExtensions_Tests : RepositoryExtensions_Tests +{ + +} diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/RepositoryExtensions_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/RepositoryExtensions_Tests.cs new file mode 100644 index 0000000000..747c53e333 --- /dev/null +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/RepositoryExtensions_Tests.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Modularity; +using Volo.Abp.TestApp.Domain; +using Xunit; + +namespace Volo.Abp.TestApp.Testing; + +public abstract class RepositoryExtensions_Tests : TestAppTestBase + where TStartupModule : IAbpModule +{ + protected readonly IRepository PersonRepository; + + protected RepositoryExtensions_Tests() + { + PersonRepository = GetRequiredService>(); + } + + [Fact] + public async Task EnsureExistsAsync_Test() + { + await WithUnitOfWorkAsync(async () => + { + var id = Guid.NewGuid(); + await Assert.ThrowsAsync(async () => + await PersonRepository.EnsureExistsAsync(Guid.NewGuid()) + ); + await Assert.ThrowsAsync(async () => + await PersonRepository.EnsureExistsAsync(x => x.Id == id) + ); + + await PersonRepository.EnsureExistsAsync(TestDataBuilder.UserDouglasId); + await PersonRepository.EnsureExistsAsync(x => x.Id == TestDataBuilder.UserDouglasId); + }); + } +}