diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs index fcb51a687c..937a2334f4 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs @@ -314,16 +314,26 @@ namespace Volo.Abp.Domain.Repositories.MongoDB } public override async Task DeleteManyAsync( - IEnumerable entities, - bool autoSave = false, - CancellationToken cancellationToken = default) + IEnumerable entities, + bool autoSave = false, + CancellationToken cancellationToken = default) { - var entityArray = entities.ToArray(); + var softDeletedEntities = new List(); + var hardDeletedEntities = new List(); - foreach (var entity in entityArray) + foreach (var entity in entities) { await ApplyAbpConceptsForDeletedEntityAsync(entity); SetNewConcurrencyStamp(entity); + + if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)) && !IsHardDeleted(entity)) + { + softDeletedEntities.Add(entity); + } + else + { + hardDeletedEntities.Add(entity); + } } var dbContext = await GetDbContextAsync(GetCancellationToken(cancellationToken)); @@ -331,54 +341,57 @@ namespace Volo.Abp.Domain.Repositories.MongoDB if (BulkOperationProvider != null) { - await BulkOperationProvider.DeleteManyAsync(this, entityArray, dbContext.SessionHandle, autoSave, cancellationToken); + await BulkOperationProvider.DeleteManyAsync(this, entities.ToArray(), dbContext.SessionHandle, autoSave, cancellationToken); return; } - var entitiesCount = entityArray.Count(); - - if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) + if (softDeletedEntities.Count > 0) { UpdateResult updateResult; + var softDeleteEntitiesCount = softDeletedEntities.Count; + if (dbContext.SessionHandle != null) { updateResult = await collection.UpdateManyAsync( dbContext.SessionHandle, - CreateEntitiesFilter(entityArray), - Builders.Update.Set(x => ((ISoftDelete)x).IsDeleted, true), - cancellationToken: cancellationToken); + CreateEntitiesFilter(softDeletedEntities), + Builders.Update.Set(x => ((ISoftDelete)x).IsDeleted, true) + ); } else { updateResult = await collection.UpdateManyAsync( - CreateEntitiesFilter(entityArray), - Builders.Update.Set(x => ((ISoftDelete)x).IsDeleted, true), - cancellationToken: cancellationToken); + CreateEntitiesFilter(softDeletedEntities), + Builders.Update.Set(x => ((ISoftDelete)x).IsDeleted, true) + ); } - if (updateResult.MatchedCount < entitiesCount) + if (updateResult.MatchedCount < softDeleteEntitiesCount) { ThrowOptimisticConcurrencyException(); } } - else + + if (hardDeletedEntities.Count > 0) { DeleteResult deleteResult; + var hardDeletedEntitiesCount = hardDeletedEntities.Count; + if (dbContext.SessionHandle != null) { deleteResult = await collection.DeleteManyAsync( dbContext.SessionHandle, - CreateEntitiesFilter(entityArray), - cancellationToken: cancellationToken); + CreateEntitiesFilter(hardDeletedEntities) + ); } else { deleteResult = await collection.DeleteManyAsync( - CreateEntitiesFilter(entityArray), - cancellationToken); + CreateEntitiesFilter(hardDeletedEntities) + ); } - if (deleteResult.DeletedCount < entitiesCount) + if (deleteResult.DeletedCount < hardDeletedEntitiesCount) { ThrowOptimisticConcurrencyException(); } 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 3d9b324da8..e31b64f6e4 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 @@ -1,7 +1,9 @@ using Shouldly; using System; +using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.Data; +using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; using Volo.Abp.Modularity; using Volo.Abp.TestApp.Domain; @@ -119,5 +121,40 @@ namespace Volo.Abp.TestApp.Testing john.ShouldBeNull(); } } + + [Fact] + public async Task Should_HardDelete_WithDeleteMany() + { + var persons = await PersonRepository.GetListAsync(); + + await WithUnitOfWorkAsync(async () => + { + var hardDeleteEntities = (HashSet)UnitOfWorkManager.Current.Items.GetOrAdd( + UnitOfWorkItemNames.HardDeletedEntities, + () => new HashSet() + ); + hardDeleteEntities.UnionWith(persons); + await PersonRepository.DeleteManyAsync(persons); + }); + + var personsCount = await PersonRepository.GetCountAsync(); + + personsCount.ShouldBe(0); + } + + [Fact] + public async Task Should_HardDelete_WithDeleteMany_WithPredicate() + { + await WithUnitOfWorkAsync(async () => + { + await PersonRepository.HardDeleteAsync(x => x.Id == TestDataBuilder.UserDouglasId); + + await PersonRepository.DeleteManyAsync(new[] { TestDataBuilder.UserDouglasId }); + }); + + var douglas = await PersonRepository.FindAsync(TestDataBuilder.UserDouglasId); + + douglas.ShouldBeNull(); + } } }