From 1b8f795e00d9c4bfe7f5507793ad7b9eb983d80a Mon Sep 17 00:00:00 2001 From: Sean Garrett Date: Sat, 17 Jun 2023 17:49:49 +0100 Subject: [PATCH] added cancellation tokens to sync deletes and added more unit tests --- .../DeleteTests/DeleteManyTests.cs | 166 ++++++++++++++++-- .../DeleteManyAsyncTests.cs | 157 +++++++++++++++++ .../MongoDbEraserTests/DeleteManyTests.cs | 157 +++++++++++++++++ .../MongoDbEraserTests/DeleteOneAsyncTests.cs | 85 +++++++++ .../MongoDbEraserTests/DeleteOneTests.cs | 132 +------------- .../Model/PartitionedTestDocument.cs | 2 +- .../DeleteTests/DeleteManyTests.cs | 97 +++++++++- .../BaseMongoRepository.Delete.cs | 84 +++++++-- .../DataAccess/Delete/IMongoDbEraser.cs | 10 +- .../DataAccess/Delete/MongoDbEraser.cs | 35 ++-- .../IBaseMongoRepository.Delete.cs | 52 +++++- .../BaseMongoRepository.TKey.Delete.cs | 34 +++- .../IBaseMongoRepository.TKey.Delete.cs | 42 ++++- 13 files changed, 861 insertions(+), 192 deletions(-) create mode 100644 CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteManyAsyncTests.cs create mode 100644 CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteManyTests.cs create mode 100644 CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteOneAsyncTests.cs diff --git a/CoreUnitTests/BaseMongoRepositoryTests/DeleteTests/DeleteManyTests.cs b/CoreUnitTests/BaseMongoRepositoryTests/DeleteTests/DeleteManyTests.cs index dbe19b6..afa1cb4 100644 --- a/CoreUnitTests/BaseMongoRepositoryTests/DeleteTests/DeleteManyTests.cs +++ b/CoreUnitTests/BaseMongoRepositoryTests/DeleteTests/DeleteManyTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using System.Threading; using AutoFixture; using CoreUnitTests.Infrastructure; using CoreUnitTests.Infrastructure.Model; @@ -23,7 +24,7 @@ public class DeleteManyTests : TestMongoRepositoryContext Eraser = new Mock(); Eraser - .Setup(x => x.DeleteMany(It.IsAny>())) + .Setup(x => x.DeleteMany(It.IsAny>(), It.IsAny())) .Returns(count); // Act @@ -31,7 +32,28 @@ public class DeleteManyTests : TestMongoRepositoryContext // Assert result.Should().Be(count); - Eraser.Verify(x => x.DeleteMany(documents), Times.Once); + Eraser.Verify(x => x.DeleteMany(documents, CancellationToken.None), Times.Once); + } + + [Fact] + public void WithDocumentsAndCancellationToken_ShouldDeleteMany() + { + // Arrange + var documents = Fixture.CreateMany().ToList(); + var count = Fixture.Create(); + var token = new CancellationToken(true); + Eraser = new Mock(); + + Eraser + .Setup(x => x.DeleteMany(It.IsAny>(), It.IsAny())) + .Returns(count); + + // Act + var result = Sut.DeleteMany(documents, token); + + // Assert + result.Should().Be(count); + Eraser.Verify(x => x.DeleteMany(documents, token), Times.Once); } [Fact] @@ -46,7 +68,7 @@ public class DeleteManyTests : TestMongoRepositoryContext Eraser = new Mock(); Eraser - .Setup(x => x.DeleteMany(It.IsAny>>(), null)) + .Setup(x => x.DeleteMany(It.IsAny>>(), It.IsAny(), It.IsAny())) .Returns(count); // Act @@ -54,7 +76,31 @@ public class DeleteManyTests : TestMongoRepositoryContext // Assert result.Should().Be(count); - Eraser.Verify(x => x.DeleteMany(filter, null), Times.Once); + Eraser.Verify(x => x.DeleteMany(filter, null, CancellationToken.None), Times.Once); + } + + [Fact] + public void WithFilterAndCancellationToken_ShouldDeleteMany() + { + // Arrange + var content = Fixture.Create(); + var count = Fixture.Create(); + var token = new CancellationToken(true); + + Expression> filter = x => x.SomeContent == content; + + Eraser = new Mock(); + + Eraser + .Setup(x => x.DeleteMany(It.IsAny>>(), It.IsAny(), It.IsAny())) + .Returns(count); + + // Act + var result = Sut.DeleteMany(filter, token); + + // Assert + result.Should().Be(count); + Eraser.Verify(x => x.DeleteMany(filter, null, token), Times.Once); } [Fact] @@ -70,7 +116,7 @@ public class DeleteManyTests : TestMongoRepositoryContext Eraser = new Mock(); Eraser - .Setup(x => x.DeleteMany(It.IsAny>>(), It.IsAny())) + .Setup(x => x.DeleteMany(It.IsAny>>(), It.IsAny(), It.IsAny())) .Returns(count); // Act @@ -78,7 +124,32 @@ public class DeleteManyTests : TestMongoRepositoryContext // Assert result.Should().Be(count); - Eraser.Verify(x => x.DeleteMany(filter, partitionKey), Times.Once); + Eraser.Verify(x => x.DeleteMany(filter, partitionKey, CancellationToken.None), Times.Once); + } + + [Fact] + public void WithFilterAndPartitionKeyAndCancellationToken_ShouldDeleteMany() + { + // Arrange + var content = Fixture.Create(); + var count = Fixture.Create(); + var partitionKey = Fixture.Create(); + var token = new CancellationToken(true); + + Expression> filter = x => x.SomeContent == content; + + Eraser = new Mock(); + + Eraser + .Setup(x => x.DeleteMany(It.IsAny>>(), It.IsAny(), It.IsAny())) + .Returns(count); + + // Act + var result = Sut.DeleteMany(filter, partitionKey, token); + + // Assert + result.Should().Be(count); + Eraser.Verify(x => x.DeleteMany(filter, partitionKey, token), Times.Once); } #region Keyed @@ -92,7 +163,7 @@ public class DeleteManyTests : TestMongoRepositoryContext Eraser = new Mock(); Eraser - .Setup(x => x.DeleteMany, int>(It.IsAny>>())) + .Setup(x => x.DeleteMany, int>(It.IsAny>>(), It.IsAny())) .Returns(count); // Act @@ -100,7 +171,28 @@ public class DeleteManyTests : TestMongoRepositoryContext // Assert result.Should().Be(count); - Eraser.Verify(x => x.DeleteMany, int>(documents), Times.Once); + Eraser.Verify(x => x.DeleteMany, int>(documents, CancellationToken.None), Times.Once); + } + + [Fact] + public void Keyed_WithDocumentsAndCancellationToken_ShouldDeleteMany() + { + // Arrange + var documents = Fixture.CreateMany>().ToList(); + var count = Fixture.Create(); + var token = new CancellationToken(true); + Eraser = new Mock(); + + Eraser + .Setup(x => x.DeleteMany, int>(It.IsAny>>(), It.IsAny())) + .Returns(count); + + // Act + var result = Sut.DeleteMany, int>(documents, token); + + // Assert + result.Should().Be(count); + Eraser.Verify(x => x.DeleteMany, int>(documents, token), Times.Once); } [Fact] @@ -115,7 +207,7 @@ public class DeleteManyTests : TestMongoRepositoryContext Eraser = new Mock(); Eraser - .Setup(x => x.DeleteMany, int>(It.IsAny, bool>>>(), null)) + .Setup(x => x.DeleteMany, int>(It.IsAny, bool>>>(), null, CancellationToken.None)) .Returns(count); // Act @@ -123,7 +215,31 @@ public class DeleteManyTests : TestMongoRepositoryContext // Assert result.Should().Be(count); - Eraser.Verify(x => x.DeleteMany, int>(filter, null), Times.Once); + Eraser.Verify(x => x.DeleteMany, int>(filter, null, CancellationToken.None), Times.Once); + } + + [Fact] + public void Keyed_WithFilterAndCancellationToken_ShouldDeleteMany() + { + // Arrange + var content = Fixture.Create(); + var count = Fixture.Create(); + var token = new CancellationToken(true); + + Expression, bool>> filter = x => x.SomeContent == content; + + Eraser = new Mock(); + + Eraser + .Setup(x => x.DeleteMany, int>(It.IsAny, bool>>>(), It.IsAny(), It.IsAny())) + .Returns(count); + + // Act + var result = Sut.DeleteMany, int>(filter, token); + + // Assert + result.Should().Be(count); + Eraser.Verify(x => x.DeleteMany, int>(filter, null, token), Times.Once); } [Fact] @@ -139,7 +255,7 @@ public class DeleteManyTests : TestMongoRepositoryContext Eraser = new Mock(); Eraser - .Setup(x => x.DeleteMany, int>(It.IsAny, bool>>>(), It.IsAny())) + .Setup(x => x.DeleteMany, int>(It.IsAny, bool>>>(), It.IsAny(), It.IsAny())) .Returns(count); // Act @@ -147,8 +263,32 @@ public class DeleteManyTests : TestMongoRepositoryContext // Assert result.Should().Be(count); - Eraser.Verify(x => x.DeleteMany, int>(filter, partitionKey), Times.Once); + Eraser.Verify(x => x.DeleteMany, int>(filter, partitionKey, CancellationToken.None), Times.Once); } + [Fact] + public void Keyed_WithFilterAndPartitionKeyAndCancellationToken_ShouldDeleteMany() + { + // Arrange + var content = Fixture.Create(); + var count = Fixture.Create(); + var partitionKey = Fixture.Create(); + var token = new CancellationToken(true); + + Expression, bool>> filter = x => x.SomeContent == content; + + Eraser = new Mock(); + + Eraser + .Setup(x => x.DeleteMany, int>(It.IsAny, bool>>>(), It.IsAny(), It.IsAny())) + .Returns(count); + + // Act + var result = Sut.DeleteMany, int>(filter, partitionKey, token); + + // Assert + result.Should().Be(count); + Eraser.Verify(x => x.DeleteMany, int>(filter, partitionKey, token), Times.Once); + } #endregion -} \ No newline at end of file +} diff --git a/CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteManyAsyncTests.cs b/CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteManyAsyncTests.cs new file mode 100644 index 0000000..8dbc7ab --- /dev/null +++ b/CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteManyAsyncTests.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; +using AutoFixture; +using CoreUnitTests.Infrastructure; +using CoreUnitTests.Infrastructure.Model; +using FluentAssertions; +using MongoDB.Driver; +using MongoDbGenericRepository; +using MongoDbGenericRepository.DataAccess.Delete; +using Moq; +using Xunit; + +namespace CoreUnitTests.DataAccessTests.MongoDbEraserTests; + +public class DeleteManyAsyncTests : GenericTestContext +{ + [Fact] + public async Task WithEmptyDocuments_DeletesNothing() + { + // Arrange + var documents = new List(0); + var token = new CancellationToken(true); + + var collection = MockOf>(); + + var dbContext = MockOf(); + dbContext + .Setup(x => x.GetCollection(null)) + .Returns(collection.Object); + + // Act + var result = await Sut.DeleteManyAsync(documents, token); + + // Assert + result.Should().Be(0); + + var idsToDelete = documents.Select(e => e.Id).ToArray(); + Expression> expectedFilter = x => idsToDelete.Contains(x.Id); + collection.Verify( + x => x.DeleteManyAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + token), + Times.Never); + } + + [Fact] + public async Task WithDocumentsAndCancellationToken_DeletesMany() + { + // Arrange + var count = Fixture.Create(); + var documents = Fixture.CreateMany().ToList(); + var token = new CancellationToken(true); + + var collection = MockOf>(); + collection + .Setup(x => x.DeleteManyAsync(It.IsAny>(), It.IsAny())) + .ReturnsAsync(new DeleteResult.Acknowledged(count)); + + var dbContext = MockOf(); + dbContext + .Setup(x => x.GetCollection(null)) + .Returns(collection.Object); + + // Act + var result = await Sut.DeleteManyAsync(documents, token); + + // Assert + result.Should().Be(count); + + var idsToDelete = documents.Select(e => e.Id).ToArray(); + Expression> expectedFilter = x => idsToDelete.Contains(x.Id); + collection.Verify( + x => x.DeleteManyAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + token), + Times.Once); + } + + [Fact] + public async Task WithPartitionDocumentsAndCancellationToken_DeletesMany() + { + // Arrange + var count = Fixture.Create(); + var partitionKey = Fixture.Create(); + var documents = Fixture + .Build() + .With(x => x.PartitionKey, partitionKey) + .CreateMany() + .ToList(); + var token = new CancellationToken(true); + + var collection = MockOf>(); + collection + .Setup(x => x.DeleteManyAsync(It.IsAny>(), It.IsAny())) + .ReturnsAsync(new DeleteResult.Acknowledged(count)); + + var dbContext = MockOf(); + dbContext + .Setup(x => x.GetCollection(It.IsAny())) + .Returns(collection.Object); + + // Act + var result = await Sut.DeleteManyAsync(documents, token); + + // Assert + result.Should().Be(count); + + var idsToDelete = documents.Select(e => e.Id).ToArray(); + Expression> expectedFilter = x => idsToDelete.Contains(x.Id); + collection.Verify( + x => x.DeleteManyAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + token), + Times.Once); + + dbContext.Verify(x => x.GetCollection(partitionKey), Times.Once); + } + + [Fact] + public async Task WithFilterAndPartitionKeyAndCancellationToken_DeletesOne() + { + // Arrange + var count = Fixture.Create(); + var id = Fixture.Create(); + var partitionKey = Fixture.Create(); + var token = new CancellationToken(true); + + var collection = MockOf>(); + collection + .Setup(x => x.DeleteManyAsync(It.IsAny>(), It.IsAny())) + .ReturnsAsync(new DeleteResult.Acknowledged(count)); + + var dbContext = MockOf(); + dbContext + .Setup(x => x.GetCollection(It.IsAny())) + .Returns(collection.Object); + + Expression> filter = d => d.Id == id; + + // Act + var result = await Sut.DeleteManyAsync(filter, partitionKey, token); + + // Assert + result.Should().Be(count); + collection.Verify( + x => x.DeleteManyAsync( + It.Is>(f => f.EquivalentTo(filter)), + token), + Times.Once); + + dbContext.Verify(x => x.GetCollection(partitionKey), Times.Once); + } +} diff --git a/CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteManyTests.cs b/CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteManyTests.cs new file mode 100644 index 0000000..276dc12 --- /dev/null +++ b/CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteManyTests.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; +using AutoFixture; +using CoreUnitTests.Infrastructure; +using CoreUnitTests.Infrastructure.Model; +using FluentAssertions; +using MongoDB.Driver; +using MongoDbGenericRepository; +using MongoDbGenericRepository.DataAccess.Delete; +using Moq; +using Xunit; + +namespace CoreUnitTests.DataAccessTests.MongoDbEraserTests; + +public class DeleteManyTests : GenericTestContext +{ + [Fact] + public void WithEmptyDocuments_DeletesNothing() + { + // Arrange + var documents = new List(0); + var token = new CancellationToken(true); + + var collection = MockOf>(); + + var dbContext = MockOf(); + dbContext + .Setup(x => x.GetCollection(null)) + .Returns(collection.Object); + + // Act + var result = Sut.DeleteMany(documents, token); + + // Assert + result.Should().Be(0); + + var idsToDelete = documents.Select(e => e.Id).ToArray(); + Expression> expectedFilter = x => idsToDelete.Contains(x.Id); + collection.Verify( + x => x.DeleteMany( + It.Is>(f => f.EquivalentTo(expectedFilter)), + token), + Times.Never); + } + + [Fact] + public void WithDocumentsAndCancellationToken_DeletesMany() + { + // Arrange + var count = Fixture.Create(); + var documents = Fixture.CreateMany().ToList(); + var token = new CancellationToken(true); + + var collection = MockOf>(); + collection + .Setup(x => x.DeleteMany(It.IsAny>(), It.IsAny())) + .Returns(new DeleteResult.Acknowledged(count)); + + var dbContext = MockOf(); + dbContext + .Setup(x => x.GetCollection(null)) + .Returns(collection.Object); + + // Act + var result = Sut.DeleteMany(documents, token); + + // Assert + result.Should().Be(count); + + var idsToDelete = documents.Select(e => e.Id).ToArray(); + Expression> expectedFilter = x => idsToDelete.Contains(x.Id); + collection.Verify( + x => x.DeleteMany( + It.Is>(f => f.EquivalentTo(expectedFilter)), + token), + Times.Once); + } + + [Fact] + public void WithPartitionDocumentsAndCancellationToken_DeletesMany() + { + // Arrange + var count = Fixture.Create(); + var partitionKey = Fixture.Create(); + var documents = Fixture + .Build() + .With(x => x.PartitionKey, partitionKey) + .CreateMany() + .ToList(); + var token = new CancellationToken(true); + + var collection = MockOf>(); + collection + .Setup(x => x.DeleteMany(It.IsAny>(), It.IsAny())) + .Returns(new DeleteResult.Acknowledged(count)); + + var dbContext = MockOf(); + dbContext + .Setup(x => x.GetCollection(It.IsAny())) + .Returns(collection.Object); + + // Act + var result = Sut.DeleteMany(documents, token); + + // Assert + result.Should().Be(count); + + var idsToDelete = documents.Select(e => e.Id).ToArray(); + Expression> expectedFilter = x => idsToDelete.Contains(x.Id); + collection.Verify( + x => x.DeleteMany( + It.Is>(f => f.EquivalentTo(expectedFilter)), + token), + Times.Once); + + dbContext.Verify(x => x.GetCollection(partitionKey), Times.Once); + } + + [Fact] + public void WithFilterAndPartitionKeyAndCancellationToken_DeletesOne() + { + // Arrange + var count = Fixture.Create(); + var id = Fixture.Create(); + var partitionKey = Fixture.Create(); + var token = new CancellationToken(true); + + var collection = MockOf>(); + collection + .Setup(x => x.DeleteMany(It.IsAny>(), It.IsAny())) + .Returns(new DeleteResult.Acknowledged(count)); + + var dbContext = MockOf(); + dbContext + .Setup(x => x.GetCollection(It.IsAny())) + .Returns(collection.Object); + + Expression> filter = d => d.Id == id; + + // Act + var result = Sut.DeleteMany(filter, partitionKey, token); + + // Assert + result.Should().Be(count); + collection.Verify( + x => x.DeleteMany( + It.Is>(f => f.EquivalentTo(filter)), + token), + Times.Once); + + dbContext.Verify(x => x.GetCollection(partitionKey), Times.Once); + } +} diff --git a/CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteOneAsyncTests.cs b/CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteOneAsyncTests.cs new file mode 100644 index 0000000..bf1b27d --- /dev/null +++ b/CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteOneAsyncTests.cs @@ -0,0 +1,85 @@ +using System; +using System.Linq.Expressions; +using System.Threading; +using System.Threading.Tasks; +using AutoFixture; +using CoreUnitTests.Infrastructure; +using CoreUnitTests.Infrastructure.Model; +using FluentAssertions; +using MongoDB.Driver; +using MongoDbGenericRepository; +using MongoDbGenericRepository.DataAccess.Delete; +using Moq; +using Xunit; + +namespace CoreUnitTests.DataAccessTests.MongoDbEraserTests; + +public class DeleteOneAsyncTests : GenericTestContext +{ + [Fact] + public async Task WithDocumentAndCancellationToken_DeletesOne() + { + // Arrange + var count = Fixture.Create(); + var document = Fixture.Create(); + var token = new CancellationToken(true); + + var collection = MockOf>(); + collection + .Setup(x => x.DeleteOneAsync(It.IsAny>(), It.IsAny())) + .ReturnsAsync(new DeleteResult.Acknowledged(count)); + + var dbContext = MockOf(); + dbContext + .Setup(x => x.GetCollection(null)) + .Returns(collection.Object); + + // Act + var result = await Sut.DeleteOneAsync(document, token); + + // Assert + result.Should().Be(count); + + var expectedFilter = Builders.Filter.Eq("Id", document.Id); + collection.Verify( + x => x.DeleteOneAsync( + It.Is>(f => f.EquivalentTo(expectedFilter)), + token), + Times.Once()); + } + + [Fact] + public async Task WithFilterAndPartitionKeyAndCancellationToken_DeletesOne() + { + // Arrange + var count = Fixture.Create(); + var document = Fixture.Create(); + var partitionKey = Fixture.Create(); + var token = new CancellationToken(true); + + var collection = MockOf>(); + collection + .Setup(x => x.DeleteOneAsync(It.IsAny>(), It.IsAny())) + .ReturnsAsync(new DeleteResult.Acknowledged(count)); + + var dbContext = MockOf(); + dbContext + .Setup(x => x.GetCollection(It.IsAny())) + .Returns(collection.Object); + + Expression> filter = d => d.Id == document.Id; + + // Act + var result = await Sut.DeleteOneAsync(filter, partitionKey, token); + + // Assert + result.Should().Be(count); + collection.Verify( + x => x.DeleteOneAsync( + It.Is>(f => f.EquivalentTo(filter)), + token), + Times.Once()); + + dbContext.Verify(x => x.GetCollection(partitionKey)); + } +} diff --git a/CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteOneTests.cs b/CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteOneTests.cs index a3506be..155a0e5 100644 --- a/CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteOneTests.cs +++ b/CoreUnitTests/DataAccessTests/MongoDbEraserTests/DeleteOneTests.cs @@ -15,36 +15,6 @@ namespace CoreUnitTests.DataAccessTests.MongoDbEraserTests; public class DeleteOneTests : GenericTestContext { - [Fact] - public void WithDocument_DeletesOne() - { - // Arrange - var count = Fixture.Create(); - var document = Fixture.Create(); - var collection = MockOf>(); - - collection - .Setup(x => x.DeleteOne(It.IsAny>(), It.IsAny())) - .Returns(new DeleteResult.Acknowledged(count)); - - var dbContext = MockOf(); - dbContext - .Setup(x => x.GetCollection(null)) - .Returns(Fixture.Create>()); - - // Act - var result = Sut.DeleteOne(document); - - // Assert - result.Should().Be(count); - - var expectedFilter = Builders.Filter.Eq("Id", document.Id); - collection.Verify( - x => x.DeleteOne( - It.Is>(f => f.EquivalentTo(expectedFilter)), - CancellationToken.None)); - } - [Fact] public void WithDocumentAndCancellationToken_DeletesOne() { @@ -61,7 +31,7 @@ public class DeleteOneTests : GenericTestContext var dbContext = MockOf(); dbContext .Setup(x => x.GetCollection(null)) - .Returns(Fixture.Create>()); + .Returns(collection.Object); // Act var result = Sut.DeleteOne(document, token); @@ -73,98 +43,8 @@ public class DeleteOneTests : GenericTestContext collection.Verify( x => x.DeleteOne( It.Is>(f => f.EquivalentTo(expectedFilter)), - token)); - } - - [Fact] - public void WithFilter_DeletesOne() - { - // Arrange - var count = Fixture.Create(); - var document = Fixture.Create(); - - var collection = MockOf>(); - collection - .Setup(x => x.DeleteOne(It.IsAny>(), It.IsAny())) - .Returns(new DeleteResult.Acknowledged(count)); - - var dbContext = MockOf(); - dbContext - .Setup(x => x.GetCollection(null)) - .Returns(Fixture.Create>()); - - Expression> filter = d => d.SomeContent == document.SomeContent; - - // Act - var result = Sut.DeleteOne(filter); - - // Assert - result.Should().Be(count); - collection.Verify( - x => x.DeleteOne( - It.Is>(f => f.EquivalentTo(filter)), CancellationToken.None)); - } - - [Fact] - public void WithFilterAndCancellationToken_DeletesOne() - { - // Arrange - var count = Fixture.Create(); - var document = Fixture.Create(); - var token = new CancellationToken(true); - - var collection = MockOf>(); - collection - .Setup(x => x.DeleteOne(It.IsAny>(), It.IsAny())) - .Returns(new DeleteResult.Acknowledged(count)); - - var dbContext = MockOf(); - dbContext - .Setup(x => x.GetCollection(null)) - .Returns(Fixture.Create>()); - - Expression> filter = d => d.Id == document.Id; - - // Act - var result = Sut.DeleteOne(filter, cancellationToken: token); - - // Assert - result.Should().Be(count); - collection.Verify( - x => x.DeleteOne( - It.Is>(f => f.EquivalentTo(filter)), token)); - } - - [Fact] - public void WithFilterAndPartitionKey_DeletesOne() - { - // Arrange - var count = Fixture.Create(); - var document = Fixture.Create(); - var partitionKey = Fixture.Create(); - - var collection = MockOf>(); - collection - .Setup(x => x.DeleteOne(It.IsAny>(), It.IsAny())) - .Returns(new DeleteResult.Acknowledged(count)); - - var dbContext = MockOf(); - dbContext - .Setup(x => x.GetCollection(It.IsAny())) - .Returns(Fixture.Create>()); - - Expression> filter = d => d.Id == document.Id; - - // Act - var result = Sut.DeleteOne(filter, partitionKey); - - // Assert - result.Should().Be(count); - collection.Verify( - x => x.DeleteOne( - It.Is>(f => f.EquivalentTo(filter)), CancellationToken.None)); - - dbContext.Verify(x => x.GetCollection(partitionKey)); + token), + Times.Once()); } [Fact] @@ -184,7 +64,7 @@ public class DeleteOneTests : GenericTestContext var dbContext = MockOf(); dbContext .Setup(x => x.GetCollection(It.IsAny())) - .Returns(Fixture.Create>()); + .Returns(collection.Object); Expression> filter = d => d.Id == document.Id; @@ -195,7 +75,9 @@ public class DeleteOneTests : GenericTestContext result.Should().Be(count); collection.Verify( x => x.DeleteOne( - It.Is>(f => f.EquivalentTo(filter)), token)); + It.Is>(f => f.EquivalentTo(filter)), + token), + Times.Once()); dbContext.Verify(x => x.GetCollection(partitionKey)); } diff --git a/CoreUnitTests/Infrastructure/Model/PartitionedTestDocument.cs b/CoreUnitTests/Infrastructure/Model/PartitionedTestDocument.cs index da6e69f..082e5aa 100644 --- a/CoreUnitTests/Infrastructure/Model/PartitionedTestDocument.cs +++ b/CoreUnitTests/Infrastructure/Model/PartitionedTestDocument.cs @@ -6,4 +6,4 @@ public class PartitionedTestDocument : TestDocument, IPartitionedDocument { /// public string PartitionKey { get; set; } = "PartitionedTestDocument"; -} \ No newline at end of file +} diff --git a/CoreUnitTests/KeyTypedRepositoryTests/DeleteTests/DeleteManyTests.cs b/CoreUnitTests/KeyTypedRepositoryTests/DeleteTests/DeleteManyTests.cs index 90e3b85..8bcddfa 100644 --- a/CoreUnitTests/KeyTypedRepositoryTests/DeleteTests/DeleteManyTests.cs +++ b/CoreUnitTests/KeyTypedRepositoryTests/DeleteTests/DeleteManyTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using System.Threading; using AutoFixture; using CoreUnitTests.Infrastructure; using CoreUnitTests.Infrastructure.Model; @@ -23,7 +24,7 @@ public class DeleteManyTests : TestKeyedMongoRepositoryContext Eraser = new Mock(); Eraser - .Setup(x => x.DeleteMany, int>(It.IsAny>>())) + .Setup(x => x.DeleteMany, int>(It.IsAny>>(), CancellationToken.None)) .Returns(count); // Act @@ -31,7 +32,29 @@ public class DeleteManyTests : TestKeyedMongoRepositoryContext // Assert result.Should().Be(count); - Eraser.Verify(x => x.DeleteMany, int>(documents), Times.Once); + Eraser.Verify(x => x.DeleteMany, int>(documents, CancellationToken.None), Times.Once); + } + + [Fact] + public void WithDocumentsAndCancellationToken_ShouldDeleteMany() + { + // Arrange + var documents = Fixture.CreateMany>().ToList(); + var count = Fixture.Create(); + var token = new CancellationToken(true); + + Eraser = new Mock(); + + Eraser + .Setup(x => x.DeleteMany, int>(It.IsAny>>(), It.IsAny())) + .Returns(count); + + // Act + var result = Sut.DeleteMany(documents, token); + + // Assert + result.Should().Be(count); + Eraser.Verify(x => x.DeleteMany, int>(documents, token), Times.Once); } [Fact] @@ -46,7 +69,7 @@ public class DeleteManyTests : TestKeyedMongoRepositoryContext Eraser = new Mock(); Eraser - .Setup(x => x.DeleteMany, int>(It.IsAny, bool>>>(), null)) + .Setup(x => x.DeleteMany, int>(It.IsAny, bool>>>(), null, CancellationToken.None)) .Returns(count); // Act @@ -54,7 +77,35 @@ public class DeleteManyTests : TestKeyedMongoRepositoryContext // Assert result.Should().Be(count); - Eraser.Verify(x => x.DeleteMany, int>(filter, null), Times.Once); + Eraser.Verify(x => x.DeleteMany, int>(filter, null, CancellationToken.None), Times.Once); + } + + [Fact] + public void WithFilterAndCancellationToken_ShouldDeleteMany() + { + // Arrange + var content = Fixture.Create(); + var count = Fixture.Create(); + var token = new CancellationToken(true); + + Expression, bool>> filter = x => x.SomeContent == content; + + Eraser = new Mock(); + + Eraser + .Setup( + x => x.DeleteMany, int>( + It.IsAny, bool>>>(), + It.IsAny(), + It.IsAny())) + .Returns(count); + + // Act + var result = Sut.DeleteMany(filter, token); + + // Assert + result.Should().Be(count); + Eraser.Verify(x => x.DeleteMany, int>(filter, null, token), Times.Once); } [Fact] @@ -70,7 +121,11 @@ public class DeleteManyTests : TestKeyedMongoRepositoryContext Eraser = new Mock(); Eraser - .Setup(x => x.DeleteMany, int>(It.IsAny, bool>>>(), It.IsAny())) + .Setup( + x => x.DeleteMany, int>( + It.IsAny, bool>>>(), + It.IsAny(), + CancellationToken.None)) .Returns(count); // Act @@ -78,6 +133,34 @@ public class DeleteManyTests : TestKeyedMongoRepositoryContext // Assert result.Should().Be(count); - Eraser.Verify(x => x.DeleteMany, int>(filter, partitionKey), Times.Once); + Eraser.Verify(x => x.DeleteMany, int>(filter, partitionKey, CancellationToken.None), Times.Once); } -} \ No newline at end of file + + [Fact] + public void WithFilterAndPartitionKeyAndCancellationToken_ShouldDeleteMany() + { + // Arrange + var content = Fixture.Create(); + var count = Fixture.Create(); + var partitionKey = Fixture.Create(); + var token = new CancellationToken(true); + + Expression, bool>> filter = x => x.SomeContent == content; + + Eraser = new Mock(); + + Eraser + .Setup(x => x.DeleteMany, int>( + It.IsAny, bool>>>(), + It.IsAny(), + It.IsAny())) + .Returns(count); + + // Act + var result = Sut.DeleteMany(filter, partitionKey, token); + + // Assert + result.Should().Be(count); + Eraser.Verify(x => x.DeleteMany, int>(filter, partitionKey, token), Times.Once); + } +} diff --git a/MongoDbGenericRepository/BaseMongoRepository.Delete.cs b/MongoDbGenericRepository/BaseMongoRepository.Delete.cs index 76a17a1..ebb8fd8 100644 --- a/MongoDbGenericRepository/BaseMongoRepository.Delete.cs +++ b/MongoDbGenericRepository/BaseMongoRepository.Delete.cs @@ -47,10 +47,9 @@ namespace MongoDbGenericRepository public virtual long DeleteOne(TDocument document, CancellationToken cancellationToken) where TDocument : IDocument { - return MongoDbEraser.DeleteOne(document, cancellationToken); + return DeleteOne(document, cancellationToken); } - /// public virtual long DeleteOne(Expression> filter) where TDocument : IDocument @@ -76,7 +75,7 @@ namespace MongoDbGenericRepository public virtual long DeleteOne(Expression> filter, string partitionKey, CancellationToken cancellationToken) where TDocument : IDocument { - return MongoDbEraser.DeleteOne(filter, partitionKey, cancellationToken); + return DeleteOne(filter, partitionKey, cancellationToken); } /// @@ -90,10 +89,9 @@ namespace MongoDbGenericRepository public virtual async Task DeleteOneAsync(TDocument document, CancellationToken cancellationToken) where TDocument : IDocument { - return await MongoDbEraser.DeleteOneAsync(document, cancellationToken); + return await DeleteOneAsync(document, cancellationToken); } - /// public virtual async Task DeleteOneAsync(Expression> filter) where TDocument : IDocument @@ -119,7 +117,7 @@ namespace MongoDbGenericRepository public virtual async Task DeleteOneAsync(Expression> filter, string partitionKey, CancellationToken cancellationToken) where TDocument : IDocument { - return await MongoDbEraser.DeleteOneAsync(filter, partitionKey, cancellationToken); + return await DeleteOneAsync(filter, partitionKey, cancellationToken); } /// @@ -147,7 +145,7 @@ namespace MongoDbGenericRepository public async Task DeleteManyAsync(Expression> filter, string partitionKey, CancellationToken cancellationToken) where TDocument : IDocument { - return await MongoDbEraser.DeleteManyAsync(filter, partitionKey, cancellationToken); + return await DeleteManyAsync(filter, partitionKey, cancellationToken); } /// @@ -168,14 +166,42 @@ namespace MongoDbGenericRepository public virtual long DeleteMany(IEnumerable documents) where TDocument : IDocument { - return DeleteMany(documents); + return DeleteMany(documents, CancellationToken.None); } /// - public virtual long DeleteMany(Expression> filter, string partitionKey = null) + public virtual long DeleteMany(IEnumerable documents, CancellationToken cancellationToken) where TDocument : IDocument { - return MongoDbEraser.DeleteMany(filter, partitionKey); + return DeleteMany(documents, cancellationToken); + } + + /// + public virtual long DeleteMany(Expression> filter) + where TDocument : IDocument + { + return DeleteMany(filter, null, CancellationToken.None); + } + + /// + public virtual long DeleteMany(Expression> filter, CancellationToken cancellationToken) + where TDocument : IDocument + { + return DeleteMany(filter, null, cancellationToken); + } + + /// + public virtual long DeleteMany(Expression> filter, string partitionKey) + where TDocument : IDocument + { + return DeleteMany(filter, partitionKey, CancellationToken.None); + } + + /// + public virtual long DeleteMany(Expression> filter, string partitionKey, CancellationToken cancellationToken) + where TDocument : IDocument + { + return DeleteMany(filter, partitionKey, cancellationToken); } #endregion Delete @@ -331,15 +357,47 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - return MongoDbEraser.DeleteMany(documents); + return DeleteMany(documents, CancellationToken.None); } /// - public virtual long DeleteMany(Expression> filter, string partitionKey = null) + public virtual long DeleteMany(IEnumerable documents, CancellationToken cancellationToken) where TDocument : IDocument where TKey : IEquatable { - return MongoDbEraser.DeleteMany(filter, partitionKey); + return MongoDbEraser.DeleteMany(documents, cancellationToken); + } + + /// + public virtual long DeleteMany(Expression> filter) + where TDocument : IDocument + where TKey : IEquatable + { + return DeleteMany(filter, null, CancellationToken.None); + } + + /// + public virtual long DeleteMany(Expression> filter, CancellationToken cancellationToken) + where TDocument : IDocument + where TKey : IEquatable + { + return DeleteMany(filter, null, cancellationToken); + } + + /// + public virtual long DeleteMany(Expression> filter, string partitionKey) + where TDocument : IDocument + where TKey : IEquatable + { + return DeleteMany(filter, partitionKey, CancellationToken.None); + } + + /// + public virtual long DeleteMany(Expression> filter, string partitionKey, CancellationToken cancellationToken) + where TDocument : IDocument + where TKey : IEquatable + { + return MongoDbEraser.DeleteMany(filter, partitionKey, cancellationToken); } #endregion diff --git a/MongoDbGenericRepository/DataAccess/Delete/IMongoDbEraser.cs b/MongoDbGenericRepository/DataAccess/Delete/IMongoDbEraser.cs index 23a1eaf..f56873b 100644 --- a/MongoDbGenericRepository/DataAccess/Delete/IMongoDbEraser.cs +++ b/MongoDbGenericRepository/DataAccess/Delete/IMongoDbEraser.cs @@ -21,7 +21,7 @@ namespace MongoDbGenericRepository.DataAccess.Delete /// The document you want to delete. /// An optional cancellation token /// The number of documents deleted. - long DeleteOne(TDocument document, CancellationToken cancellationToken = default) + long DeleteOne(TDocument document, CancellationToken cancellationToken) where TDocument : IDocument where TKey : IEquatable; @@ -34,7 +34,7 @@ namespace MongoDbGenericRepository.DataAccess.Delete /// An optional partition key. /// An optional cancellation token /// The number of documents deleted. - long DeleteOne(Expression> filter, string partitionKey = null, CancellationToken cancellationToken = default) + long DeleteOne(Expression> filter, string partitionKey, CancellationToken cancellationToken) where TDocument : IDocument where TKey : IEquatable; @@ -94,8 +94,9 @@ namespace MongoDbGenericRepository.DataAccess.Delete /// The type representing a Document. /// The type of the primary key for a Document. /// The list of documents to delete. + /// The cancellation token /// The number of documents deleted. - long DeleteMany(IEnumerable documents) + long DeleteMany(IEnumerable documents, CancellationToken cancellationToken) where TDocument : IDocument where TKey : IEquatable; @@ -106,8 +107,9 @@ namespace MongoDbGenericRepository.DataAccess.Delete /// The type of the primary key for a Document. /// A LINQ expression filter. /// An optional partition key. + /// The Cancellation Token /// The number of documents deleted. - long DeleteMany(Expression> filter, string partitionKey = null) + long DeleteMany(Expression> filter, string partitionKey, CancellationToken cancellationToken) where TDocument : IDocument where TKey : IEquatable; } diff --git a/MongoDbGenericRepository/DataAccess/Delete/MongoDbEraser.cs b/MongoDbGenericRepository/DataAccess/Delete/MongoDbEraser.cs index 902b107..7136261 100644 --- a/MongoDbGenericRepository/DataAccess/Delete/MongoDbEraser.cs +++ b/MongoDbGenericRepository/DataAccess/Delete/MongoDbEraser.cs @@ -24,7 +24,7 @@ namespace MongoDbGenericRepository.DataAccess.Delete #region Delete TKey /// - public virtual long DeleteOne(TDocument document, CancellationToken cancellationToken = default) + public virtual long DeleteOne(TDocument document, CancellationToken cancellationToken) where TDocument : IDocument where TKey : IEquatable { @@ -33,7 +33,7 @@ namespace MongoDbGenericRepository.DataAccess.Delete } /// - public virtual long DeleteOne(Expression> filter, string partitionKey = null, CancellationToken cancellationToken = default) + public virtual long DeleteOne(Expression> filter, string partitionKey, CancellationToken cancellationToken) where TDocument : IDocument where TKey : IEquatable { @@ -41,7 +41,7 @@ namespace MongoDbGenericRepository.DataAccess.Delete } /// - public virtual async Task DeleteOneAsync(TDocument document, CancellationToken cancellationToken) + public virtual async Task DeleteOneAsync(TDocument document, CancellationToken cancellationToken = default) where TDocument : IDocument where TKey : IEquatable { @@ -68,7 +68,7 @@ namespace MongoDbGenericRepository.DataAccess.Delete where TDocument : IDocument where TKey : IEquatable { - return (await HandlePartitioned(partitionKey).DeleteManyAsync(filter)).DeletedCount; + return (await HandlePartitioned(partitionKey).DeleteManyAsync(filter, cancellationToken)).DeletedCount; } /// @@ -103,14 +103,8 @@ namespace MongoDbGenericRepository.DataAccess.Delete .DeletedCount; } - /// - /// Deletes a list of documents. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The list of documents to delete. - /// The number of documents deleted. - public virtual long DeleteMany(IEnumerable documents) + /// + public virtual long DeleteMany(IEnumerable documents, CancellationToken cancellationToken) where TDocument : IDocument where TKey : IEquatable { @@ -128,29 +122,22 @@ namespace MongoDbGenericRepository.DataAccess.Delete foreach (var group in documentList.GroupBy(e => ((IPartitionedDocument) e).PartitionKey)) { var groupIdsToDelete = group.Select(e => e.Id).ToArray(); - deleteCount += HandlePartitioned(group.FirstOrDefault()).DeleteMany(x => groupIdsToDelete.Contains(x.Id)).DeletedCount; + deleteCount += HandlePartitioned(group.FirstOrDefault()).DeleteMany(x => groupIdsToDelete.Contains(x.Id), cancellationToken).DeletedCount; } return deleteCount; } var idsToDelete = documentList.Select(e => e.Id).ToArray(); - return HandlePartitioned(documentList.FirstOrDefault()).DeleteMany(x => idsToDelete.Contains(x.Id)).DeletedCount; + return HandlePartitioned(documentList.FirstOrDefault()).DeleteMany(x => idsToDelete.Contains(x.Id), cancellationToken).DeletedCount; } - /// - /// Deletes the documents matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - public virtual long DeleteMany(Expression> filter, string partitionKey = null) + /// + public virtual long DeleteMany(Expression> filter, string partitionKey, CancellationToken cancellationToken) where TDocument : IDocument where TKey : IEquatable { - return HandlePartitioned(partitionKey).DeleteMany(filter).DeletedCount; + return HandlePartitioned(partitionKey).DeleteMany(filter, cancellationToken).DeletedCount; } #endregion diff --git a/MongoDbGenericRepository/IBaseMongoRepository.Delete.cs b/MongoDbGenericRepository/IBaseMongoRepository.Delete.cs index 930870f..9941b6d 100644 --- a/MongoDbGenericRepository/IBaseMongoRepository.Delete.cs +++ b/MongoDbGenericRepository/IBaseMongoRepository.Delete.cs @@ -236,6 +236,42 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable; + /// + /// Deletes a list of documents. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The list of documents to delete. + /// The cancellation token + /// The number of documents deleted. + long DeleteMany(IEnumerable documents, CancellationToken cancellationToken) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// The number of documents deleted. + long DeleteMany(Expression> filter) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// The cancellation token. + /// The number of documents deleted. + long DeleteMany(Expression> filter, CancellationToken cancellationToken) + where TDocument : IDocument + where TKey : IEquatable; + + /// /// Deletes the documents matching the condition of the LINQ expression filter. /// @@ -244,8 +280,22 @@ namespace MongoDbGenericRepository /// A LINQ expression filter. /// An optional partition key. /// The number of documents deleted. - long DeleteMany(Expression> filter, string partitionKey = null) + long DeleteMany(Expression> filter, string partitionKey) where TDocument : IDocument where TKey : IEquatable; + + /// + /// Deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The cancellation token + /// The number of documents deleted. + long DeleteMany(Expression> filter, string partitionKey, CancellationToken cancellationToken) + where TDocument : IDocument + where TKey : IEquatable; + } } \ No newline at end of file diff --git a/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Delete.cs b/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Delete.cs index 839a92b..e2d8f39 100644 --- a/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Delete.cs +++ b/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Delete.cs @@ -164,14 +164,42 @@ namespace MongoDbGenericRepository public virtual long DeleteMany(IEnumerable documents) where TDocument : IDocument { - return MongoDbEraser.DeleteMany(documents); + return DeleteMany(documents, CancellationToken.None); } /// - public virtual long DeleteMany(Expression> filter, string partitionKey = null) + public virtual long DeleteMany(IEnumerable documents, CancellationToken cancellationToken) where TDocument : IDocument { - return MongoDbEraser.DeleteMany(filter, partitionKey); + return MongoDbEraser.DeleteMany(documents, cancellationToken); + } + + /// + public virtual long DeleteMany(Expression> filter) + where TDocument : IDocument + { + return DeleteMany(filter, null, CancellationToken.None); + } + + /// + public virtual long DeleteMany(Expression> filter, CancellationToken cancellationToken) + where TDocument : IDocument + { + return DeleteMany(filter, null, cancellationToken); + } + + /// + public virtual long DeleteMany(Expression> filter, string partitionKey) + where TDocument : IDocument + { + return DeleteMany(filter, partitionKey, CancellationToken.None); + } + + /// + public virtual long DeleteMany(Expression> filter, string partitionKey, CancellationToken cancellationToken) + where TDocument : IDocument + { + return MongoDbEraser.DeleteMany(filter, partitionKey, cancellationToken); } } } diff --git a/MongoDbGenericRepository/KeyTypedRepository/IBaseMongoRepository.TKey.Delete.cs b/MongoDbGenericRepository/KeyTypedRepository/IBaseMongoRepository.TKey.Delete.cs index c747d91..883d7c9 100644 --- a/MongoDbGenericRepository/KeyTypedRepository/IBaseMongoRepository.TKey.Delete.cs +++ b/MongoDbGenericRepository/KeyTypedRepository/IBaseMongoRepository.TKey.Delete.cs @@ -201,6 +201,35 @@ namespace MongoDbGenericRepository long DeleteMany(IEnumerable documents) where TDocument : IDocument; + /// + /// Deletes a list of documents. + /// + /// The type representing a Document. + /// The list of documents to delete. + /// The cancellation token. + /// The number of documents deleted. + long DeleteMany(IEnumerable documents, CancellationToken cancellationToken) + where TDocument : IDocument; + + /// + /// Deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// A LINQ expression filter. + /// The number of documents deleted. + long DeleteMany(Expression> filter) + where TDocument : IDocument; + + /// + /// Deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// A LINQ expression filter. + /// The cancellation token + /// The number of documents deleted. + long DeleteMany(Expression> filter, CancellationToken cancellationToken) + where TDocument : IDocument; + /// /// Deletes the documents matching the condition of the LINQ expression filter. /// @@ -208,7 +237,18 @@ namespace MongoDbGenericRepository /// A LINQ expression filter. /// An optional partition key. /// The number of documents deleted. - long DeleteMany(Expression> filter, string partitionKey = null) + long DeleteMany(Expression> filter, string partitionKey) + where TDocument : IDocument; + + /// + /// Deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// + /// The number of documents deleted. + long DeleteMany(Expression> filter, string partitionKey, CancellationToken cancellationToken) where TDocument : IDocument; } } \ No newline at end of file