From 8d3e480c38238cd1218f00ee62ea012e5f10dfe0 Mon Sep 17 00:00:00 2001 From: alexandre-spieser Date: Sun, 27 Aug 2017 21:39:29 +0000 Subject: [PATCH] Added delete functionality --- IntegrationTests/DeletePartitionedTests.cs | 129 +++++++ IntegrationTests/DeleteTests.cs | 129 +++++++ IntegrationTests/IntegrationTests.csproj | 2 + IntegrationTests/UpdatePartitionedTests.cs | 4 +- MongoDbGenericRepository/MongoDbRepository.cs | 362 +++++++++++------- 5 files changed, 478 insertions(+), 148 deletions(-) create mode 100644 IntegrationTests/DeletePartitionedTests.cs create mode 100644 IntegrationTests/DeleteTests.cs diff --git a/IntegrationTests/DeletePartitionedTests.cs b/IntegrationTests/DeletePartitionedTests.cs new file mode 100644 index 0000000..24ca3d1 --- /dev/null +++ b/IntegrationTests/DeletePartitionedTests.cs @@ -0,0 +1,129 @@ +using IntegrationTests.Infrastructure; +using MongoDbGenericRepository.Models; +using NUnit.Framework; +using System.Threading.Tasks; + +namespace IntegrationTests +{ + public class DeleteTestsPartitionedDocument : PartitionedDocument + { + public DeleteTestsPartitionedDocument() : base("TestPartitionKey") + { + Version = 1; + } + public string SomeContent { get; set; } + } + + public class DeletePartitionedTests : BaseMongoDbRepositoryTests + { + [Test] + public void PartitionedDeleteOne() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = SUT.DeleteOne(document); + // Assert + Assert.AreEqual(1, result); + Assert.IsFalse(SUT.Any(e => e.Id == document.Id, PartitionKey)); + } + + [Test] + public void PartitionedDeleteOneLinq() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = SUT.DeleteOne(e => e.Id == document.Id, PartitionKey); + // Assert + Assert.AreEqual(1, result); + Assert.IsFalse(SUT.Any(e => e.Id == document.Id, PartitionKey)); + } + + [Test] + public async Task PartitionedDeleteOneAsync() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = await SUT.DeleteOneAsync(document); + // Assert + Assert.AreEqual(1, result); + Assert.IsFalse(SUT.Any(e => e.Id == document.Id, PartitionKey)); + } + + [Test] + public async Task PartitionedDeleteOneAsyncLinq() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = await SUT.DeleteOneAsync(e => e.Id == document.Id, PartitionKey); + // Assert + Assert.AreEqual(1, result); + Assert.IsFalse(SUT.Any(e => e.Id == document.Id, PartitionKey)); + } + + [Test] + public async Task PartitionedDeleteManyAsyncLinq() + { + // Arrange + var documents = CreateTestDocuments(5); + documents.ForEach(e => e.SomeContent = "DeleteManyAsyncLinqContent"); + SUT.AddMany(documents); + // Act + var result = await SUT.DeleteManyAsync(e => e.SomeContent == "DeleteManyAsyncLinqContent", PartitionKey); + // Assert + Assert.AreEqual(5, result); + Assert.IsFalse(SUT.Any(e => e.SomeContent == "DeleteManyAsyncLinqContent", PartitionKey)); + } + + [Test] + public async Task PartitionedDeleteManyAsync() + { + // Arrange + var documents = CreateTestDocuments(5); + documents.ForEach(e => e.SomeContent = "DeleteManyAsyncLinqContent"); + SUT.AddMany(documents); + // Act + var result = await SUT.DeleteManyAsync(documents); + // Assert + Assert.AreEqual(5, result); + Assert.IsFalse(SUT.Any(e => e.SomeContent == "DeleteManyAsyncLinqContent", PartitionKey)); + } + + [Test] + public void PartitionedDeleteManyLinq() + { + // Arrange + var content = "DeleteManyLinqContent"; + var documents = CreateTestDocuments(5); + documents.ForEach(e => e.SomeContent = content); + SUT.AddMany(documents); + // Act + var result = SUT.DeleteMany(e => e.SomeContent == content, PartitionKey); + // Assert + Assert.AreEqual(5, result); + Assert.IsFalse(SUT.Any(e => e.SomeContent == content, PartitionKey)); + } + + [Test] + public void PartitionedDeleteMany() + { + // Arrange + var content = "DeleteManyContent"; + var documents = CreateTestDocuments(5); + documents.ForEach(e => e.SomeContent = content); + SUT.AddMany(documents); + // Act + var result = SUT.DeleteMany(documents); + // Assert + Assert.AreEqual(5, result); + Assert.IsFalse(SUT.Any(e => e.SomeContent == content, PartitionKey)); + } + } +} diff --git a/IntegrationTests/DeleteTests.cs b/IntegrationTests/DeleteTests.cs new file mode 100644 index 0000000..ec01f75 --- /dev/null +++ b/IntegrationTests/DeleteTests.cs @@ -0,0 +1,129 @@ +using IntegrationTests.Infrastructure; +using MongoDbGenericRepository.Models; +using NUnit.Framework; +using System.Threading.Tasks; + +namespace IntegrationTests +{ + public class DeleteTestsDocument : Document + { + public DeleteTestsDocument() + { + Version = 2; + } + public string SomeContent { get; set; } + } + + public class DeleteTests : BaseMongoDbRepositoryTests + { + [Test] + public void DeleteOne() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = SUT.DeleteOne(document); + // Assert + Assert.AreEqual(1, result); + Assert.IsFalse(SUT.Any(e => e.Id == document.Id)); + } + + [Test] + public void DeleteOneLinq() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = SUT.DeleteOne(e => e.Id == document.Id); + // Assert + Assert.AreEqual(1, result); + Assert.IsFalse(SUT.Any(e => e.Id == document.Id)); + } + + [Test] + public async Task DeleteOneAsync() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = await SUT.DeleteOneAsync(document); + // Assert + Assert.AreEqual(1, result); + Assert.IsFalse(SUT.Any(e => e.Id == document.Id)); + } + + [Test] + public async Task DeleteOneAsyncLinq() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = await SUT.DeleteOneAsync(e => e.Id == document.Id); + // Assert + Assert.AreEqual(1, result); + Assert.IsFalse(SUT.Any(e => e.Id == document.Id)); + } + + [Test] + public async Task DeleteManyAsyncLinq() + { + // Arrange + var documents = CreateTestDocuments(5); + documents.ForEach(e => e.SomeContent = "DeleteManyAsyncLinqContent"); + SUT.AddMany(documents); + // Act + var result = await SUT.DeleteManyAsync(e => e.SomeContent == "DeleteManyAsyncLinqContent"); + // Assert + Assert.AreEqual(5, result); + Assert.IsFalse(SUT.Any(e => e.SomeContent == "DeleteManyAsyncLinqContent")); + } + + [Test] + public async Task DeleteManyAsync() + { + // Arrange + var documents = CreateTestDocuments(5); + documents.ForEach(e => e.SomeContent = "DeleteManyAsyncLinqContent"); + SUT.AddMany(documents); + // Act + var result = await SUT.DeleteManyAsync(documents); + // Assert + Assert.AreEqual(5, result); + Assert.IsFalse(SUT.Any(e => e.SomeContent == "DeleteManyAsyncLinqContent")); + } + + [Test] + public void DeleteManyLinq() + { + // Arrange + var content = "DeleteManyLinqContent"; + var documents = CreateTestDocuments(5); + documents.ForEach(e => e.SomeContent = content); + SUT.AddMany(documents); + // Act + var result = SUT.DeleteMany(e => e.SomeContent == content); + // Assert + Assert.AreEqual(5, result); + Assert.IsFalse(SUT.Any(e => e.SomeContent == content)); + } + + [Test] + public void DeleteMany() + { + // Arrange + var content = "DeleteManyContent"; + var documents = CreateTestDocuments(5); + documents.ForEach(e => e.SomeContent = content); + SUT.AddMany(documents); + // Act + var result = SUT.DeleteMany(documents); + // Assert + Assert.AreEqual(5, result); + Assert.IsFalse(SUT.Any(e => e.SomeContent == content)); + } + } +} diff --git a/IntegrationTests/IntegrationTests.csproj b/IntegrationTests/IntegrationTests.csproj index 7f576ad..a3ec14a 100644 --- a/IntegrationTests/IntegrationTests.csproj +++ b/IntegrationTests/IntegrationTests.csproj @@ -56,6 +56,8 @@ + + diff --git a/IntegrationTests/UpdatePartitionedTests.cs b/IntegrationTests/UpdatePartitionedTests.cs index 49776f3..3c0fa8a 100644 --- a/IntegrationTests/UpdatePartitionedTests.cs +++ b/IntegrationTests/UpdatePartitionedTests.cs @@ -17,7 +17,7 @@ namespace IntegrationTests public class UpdatePartitionedTests : BaseMongoDbRepositoryTests { [Test] - public void UpdateOne() + public void PartitionedUpdateOne() { // Arrange var document = CreateTestDocument(); @@ -33,7 +33,7 @@ namespace IntegrationTests } [Test] - public async Task UpdateOneAsync() + public async Task PartitionedUpdateOneAsync() { // Arrange var document = CreateTestDocument(); diff --git a/MongoDbGenericRepository/MongoDbRepository.cs b/MongoDbGenericRepository/MongoDbRepository.cs index 16ffdaf..f00ff93 100644 --- a/MongoDbGenericRepository/MongoDbRepository.cs +++ b/MongoDbGenericRepository/MongoDbRepository.cs @@ -155,7 +155,77 @@ namespace MongoDbGenericRepository #endregion + #region Delete + /// + /// Asynchronously deletes a document. + /// + /// + /// The document you want to delete. + /// The number of documents deleted. + Task DeleteOneAsync(TDocument document) where TDocument : IDocument; + + /// + /// Asynchronously deletes a document matching the condition of the LINQ expression filter. + /// + /// + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + Task DeleteOneAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument; + + /// + /// Deletes a document. + /// + /// + /// The document you want to delete. + /// The number of documents deleted. + long DeleteOne(TDocument document) where TDocument : IDocument; + + /// + /// Deletes a document matching the condition of the LINQ expression filter. + /// + /// + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + long DeleteOne(Expression> filter, string partitionKey = null) where TDocument : IDocument; + + /// + /// Asynchronously deletes the documents matching the condition of the LINQ expression filter. + /// + /// + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + Task DeleteManyAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument; + + /// + /// Asynchronously deletes a list of documents. + /// + /// + /// The list of documents to delete. + /// The number of documents deleted. + Task DeleteManyAsync(IEnumerable documents) where TDocument : IDocument; + + /// + /// Deletes a list of documents. + /// + /// + /// The list of documents to delete. + /// The number of documents deleted. + long DeleteMany(IEnumerable documents) where TDocument : IDocument; + + /// + /// Deletes the documents matching the condition of the LINQ expression filter. + /// + /// + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + long DeleteMany(Expression> filter, string partitionKey = null) where TDocument : IDocument; + + #endregion } @@ -373,141 +443,7 @@ namespace MongoDbGenericRepository return HandlePartitioned(partitionKey).Find(filter).Count(); } - /// - /// Asynchronously returns a paginated list of the documents matching the filter condition. - /// - /// - /// - /// The number of documents you want to skip. Default value is 0. - /// The number of documents you want to take. Default value is 50. - /// An optional partition key. - public async Task> GetPaginatedAsync(Expression> filter, int skipNumber = 0, int takeNumber = 50, string partitionKey = null) where TDocument : IDocument - { - return await HandlePartitioned(partitionKey).Find(filter).Skip(skipNumber).Limit(takeNumber).ToListAsync(); - } - - - /// - /// Returns a list of projected objects - /// - /// T is a DbEntity - /// - /// - public async Task ProjectBy(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TProjection : class, new() - { - return await HandlePartitioned(partitionKey).Find(filter) - .Project(projection) - .FirstOrDefaultAsync(); - } - - #endregion Get - - #region Delete - - /// - /// A generic delete one method - /// - /// - /// - /// - public async Task DeleteOneAsync(TDocument document) where TDocument : IDocument - { - return await DeleteOneAsync(x => x.Id == document.Id); - } - - /// - /// A generic delete one method - /// - /// - /// - /// - public long DeleteOne(TDocument document) where TDocument : IDocument - { - return DeleteOne(x => x.Id == document.Id); - } - - /// - /// A generic delete one method - /// - /// - /// - /// - public long DeleteOne(Expression> filter, string partitionKey = null) where TDocument : IDocument - { - return GetCollection().DeleteOne(filter).DeletedCount; - } - - /// - /// A generic delete one method - /// - /// - /// - /// - public async Task DeleteOneAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument - { - return (await GetCollection().DeleteOneAsync(filter)).DeletedCount; - } - - /// - /// A generic delete many method - /// - /// - /// - /// - public async Task DeleteManyAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument - { - var deleteRes = await GetCollection().DeleteManyAsync(filter); - return deleteRes.DeletedCount; - } - - /// - /// A generic delete many method - /// - /// - /// - /// - public async Task DeleteManyAsync(IEnumerable documents) where TDocument : IDocument - { - if (!documents.Any()) - { - return 0; - } - var idsTodelete = documents.Select(e => e.Id).ToArray(); - var deleteRes = await GetCollection().DeleteManyAsync(x => idsTodelete.Contains(x.Id)); - return deleteRes.DeletedCount; - } - - /// - /// A generic delete many method - /// - /// - /// - /// - public long DeleteMany(IEnumerable documents) where TDocument : IDocument - { - if (!documents.Any()) - { - return 0; - } - var idsTodelete = documents.Select(e => e.Id).ToArray(); - var deleteRes = GetCollection().DeleteMany(x => idsTodelete.Contains(x.Id)); - return deleteRes.DeletedCount; - } - - /// - /// A generic delete many method - /// - /// - /// - /// - public long DeleteMany(Expression> filter, string partitionKey = null) where TDocument : IDocument - { - var deleteRes = GetCollection().DeleteMany(filter); - return deleteRes.DeletedCount; - } - #endregion Delete + #endregion #region Update @@ -535,6 +471,147 @@ namespace MongoDbGenericRepository #endregion Update + #region Delete + + /// + /// Asynchronously deletes a document. + /// + /// + /// The document you want to delete. + /// The number of documents deleted. + public async Task DeleteOneAsync(TDocument document) where TDocument : IDocument + { + return (await HandlePartitioned(document).DeleteOneAsync(x => x.Id == document.Id)).DeletedCount; + } + + /// + /// Deletes a document. + /// + /// + /// The document you want to delete. + /// The number of documents deleted. + public long DeleteOne(TDocument document) where TDocument : IDocument + { + return HandlePartitioned(document).DeleteOne(x => x.Id == document.Id).DeletedCount; + } + + /// + /// Deletes a document matching the condition of the LINQ expression filter. + /// + /// + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public long DeleteOne(Expression> filter, string partitionKey = null) where TDocument : IDocument + { + return HandlePartitioned(partitionKey).DeleteOne(filter).DeletedCount; + } + + /// + /// Asynchronously deletes a document matching the condition of the LINQ expression filter. + /// + /// + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public async Task DeleteOneAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument + { + return (await HandlePartitioned(partitionKey).DeleteOneAsync(filter)).DeletedCount; + } + + /// + /// Asynchronously deletes the documents matching the condition of the LINQ expression filter. + /// + /// + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public async Task DeleteManyAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument + { + return (await HandlePartitioned(partitionKey).DeleteManyAsync(filter)).DeletedCount; + } + + /// + /// Asynchronously deletes a list of documents. + /// + /// + /// The list of documents to delete. + /// The number of documents deleted. + public async Task DeleteManyAsync(IEnumerable documents) where TDocument : IDocument + { + if (!documents.Any()) + { + return 0; + } + var idsTodelete = documents.Select(e => e.Id).ToArray(); + return (await HandlePartitioned(documents.FirstOrDefault()).DeleteManyAsync(x => idsTodelete.Contains(x.Id))).DeletedCount; + } + + /// + /// Deletes a list of documents. + /// + /// + /// The list of documents to delete. + /// The number of documents deleted. + public long DeleteMany(IEnumerable documents) where TDocument : IDocument + { + if (!documents.Any()) + { + return 0; + } + var idsTodelete = documents.Select(e => e.Id).ToArray(); + return HandlePartitioned(documents.FirstOrDefault()).DeleteMany(x => idsTodelete.Contains(x.Id)).DeletedCount; + } + + /// + /// Deletes the documents matching the condition of the LINQ expression filter. + /// + /// + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public long DeleteMany(Expression> filter, string partitionKey = null) where TDocument : IDocument + { + return HandlePartitioned(partitionKey).DeleteMany(filter).DeletedCount; + } + + #endregion Delete + + #region Projection + + /// + /// Asynchronously returns a list of projected document matching the filter condition. + /// + /// + /// + /// + /// The projection expression. + /// An optional partition key. + public async Task GetProjectedAsync(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TProjection : class, new() + { + return await HandlePartitioned(partitionKey).Find(filter) + .Project(projection) + .FirstOrDefaultAsync(); + } + + #endregion + + + /// + /// Asynchronously returns a paginated list of the documents matching the filter condition. + /// + /// + /// + /// The number of documents you want to skip. Default value is 0. + /// The number of documents you want to take. Default value is 50. + /// An optional partition key. + public async Task> GetPaginatedAsync(Expression> filter, int skipNumber = 0, int takeNumber = 50, string partitionKey = null) where TDocument : IDocument + { + return await HandlePartitioned(partitionKey).Find(filter).Skip(skipNumber).Limit(takeNumber).ToListAsync(); + } + #region Find And Update /// @@ -552,22 +629,13 @@ namespace MongoDbGenericRepository #endregion Find And Update - /// - /// - /// - /// - /// - /// + #region Private Methods + private IMongoCollection GetCollection(string partitionKey) where TDocument : IDocument { return _mongoDbContext.GetCollection(partitionKey); } - /// - /// The private GetCollection method - /// - /// - /// private IMongoCollection GetCollection() where TDocument : IDocument { return _mongoDbContext.GetCollection(); @@ -607,5 +675,7 @@ namespace MongoDbGenericRepository document.AddedAtUtc = DateTime.UtcNow; } } + + #endregion } } \ No newline at end of file