diff --git a/IntegrationTests/CRUDPartitionedCollectionNameAttributeTests.cs b/IntegrationTests/CRUDPartitionedCollectionNameAttributeTests.cs new file mode 100644 index 0000000..43a7440 --- /dev/null +++ b/IntegrationTests/CRUDPartitionedCollectionNameAttributeTests.cs @@ -0,0 +1,27 @@ +using IntegrationTests.Infrastructure; +using MongoDB.Bson.Serialization.Attributes; +using MongoDbGenericRepository.Attributes; +using MongoDbGenericRepository.Models; +using System; + +namespace IntegrationTests +{ + [CollectionName("TestingCollectionNameAttributePartitionedTKey")] + public class PartitionedCollectionNameDoc : TestDoc, IPartitionedDocument + { + public PartitionedCollectionNameDoc() + { + PartitionKey = "TestPartitionKey"; + } + + public string PartitionKey { get; set; } + } + + public class CRUDPartitionedCollectionNameAttributeTests : MongoDbDocumentTestBase + { + public override string GetClassName() + { + return "CRUDPartitionedCollectionNameAttributeTests"; + } + } +} diff --git a/IntegrationTests/CRUDPartitionedTests.cs b/IntegrationTests/CRUDPartitionedTests.cs new file mode 100644 index 0000000..62d4553 --- /dev/null +++ b/IntegrationTests/CRUDPartitionedTests.cs @@ -0,0 +1,23 @@ +using IntegrationTests.Infrastructure; +using MongoDbGenericRepository.Models; + +namespace IntegrationTests +{ + public class PartitionedDoc : TestDoc, IPartitionedDocument + { + public PartitionedDoc() + { + PartitionKey = "TestPartitionKey"; + } + + public string PartitionKey { get; set; } + } + + public class CRUDPartitionedTests : MongoDbDocumentTestBase + { + public override string GetClassName() + { + return "CRUDPartitionedCollectionNameAttributeTests"; + } + } +} diff --git a/IntegrationTests/CRUDTKeyPartitionedCollectionNameAttributeTests.cs b/IntegrationTests/CRUDTKeyPartitionedCollectionNameAttributeTests.cs index 3ecc77b..4b0fba5 100644 --- a/IntegrationTests/CRUDTKeyPartitionedCollectionNameAttributeTests.cs +++ b/IntegrationTests/CRUDTKeyPartitionedCollectionNameAttributeTests.cs @@ -1,5 +1,4 @@ using IntegrationTests.Infrastructure; -using MongoDB.Bson.Serialization.Attributes; using MongoDbGenericRepository.Attributes; using MongoDbGenericRepository.Models; using System; @@ -17,11 +16,11 @@ namespace IntegrationTests public string PartitionKey { get; set; } } - public class CRUDTKeyPartitionedCollectionNameAttributeTests : MongoDBTestBase + public class CRUDTKeyPartitionedCollectionNameAttributeTests : MongoDbTKeyDocumentTestBase { public override string GetClassName() { - return "TKeyPartitionedCollectionNameAttributeTests"; + return "CRUDTKeyPartitionedCollectionNameAttributeTests"; } } } diff --git a/IntegrationTests/CRUDTKeyPartitionedTests.cs b/IntegrationTests/CRUDTKeyPartitionedTests.cs index 7a8de0c..3966208 100644 --- a/IntegrationTests/CRUDTKeyPartitionedTests.cs +++ b/IntegrationTests/CRUDTKeyPartitionedTests.cs @@ -16,7 +16,7 @@ namespace IntegrationTests } [TestFixture] - public class CRUDTKeyPartitionedTests : MongoDBTestBase + public class CRUDTKeyPartitionedTests : MongoDbTKeyDocumentTestBase { public override string GetClassName() { diff --git a/IntegrationTests/CRUDTKeyTests.cs b/IntegrationTests/CRUDTKeyTests.cs index 564d67c..0929181 100644 --- a/IntegrationTests/CRUDTKeyTests.cs +++ b/IntegrationTests/CRUDTKeyTests.cs @@ -11,7 +11,7 @@ namespace IntegrationTests } [TestFixture] - public class CRUDTKeyTests : MongoDBTestBase + public class CRUDTKeyTests : MongoDbTKeyDocumentTestBase { public override string GetClassName() { diff --git a/IntegrationTests/CRUDTests.cs b/IntegrationTests/CRUDTests.cs new file mode 100644 index 0000000..f1fc55e --- /dev/null +++ b/IntegrationTests/CRUDTests.cs @@ -0,0 +1,18 @@ +using IntegrationTests.Infrastructure; +using NUnit.Framework; + +namespace IntegrationTests +{ + public class TestDocument : TestDoc + { + } + + [TestFixture] + public class CRUDTests : MongoDbDocumentTestBase + { + public override string GetClassName() + { + return "CRUDTests"; + } + } +} diff --git a/IntegrationTests/Infrastructure/MongoDBDocumentTestBase.cs b/IntegrationTests/Infrastructure/MongoDBDocumentTestBase.cs new file mode 100644 index 0000000..6711c9f --- /dev/null +++ b/IntegrationTests/Infrastructure/MongoDBDocumentTestBase.cs @@ -0,0 +1,755 @@ +using MongoDB.Bson.Serialization.Attributes; +using MongoDbGenericRepository.Models; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Diagnostics; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +namespace IntegrationTests.Infrastructure +{ + public class TestDoc : Document + { + public TestDoc() + { + Version = 2; + Nested = new Nested + { + SomeDate = DateTime.UtcNow + }; + Children = new List(); + } + + public string SomeContent { get; set; } + + public Nested Nested { get; set; } + + public List Children { get; set; } + + } + + + [TestFixture] + public abstract class MongoDbDocumentTestBase + where T: TestDoc, new() + { + public T CreateTestDocument() + { + return new T(); + } + + public abstract string GetClassName(); + + public List CreateTestDocuments(int numberOfDocumentsToCreate) + { + var docs = new List(); + for (var i = 0; i < numberOfDocumentsToCreate; i++) + { + docs.Add(new T()); + } + return docs; + } + + /// + /// The partition key for the collection, if any + /// + protected string PartitionKey { get; set; } + + /// + /// the name of the test class + /// + protected string TestClassName { get; set; } + + /// + /// The name of the document used for tests + /// + protected string DocumentTypeName { get; set; } + + /// + /// SUT: System Under Test + /// + protected static ITestRepository SUT { get; set; } + + public MongoDbDocumentTestBase() + { + var type = CreateTestDocument(); + DocumentTypeName = type.GetType().FullName; + if (type is IPartitionedDocument) + { + PartitionKey = ((IPartitionedDocument)type).PartitionKey; + } + TestClassName = GetClassName(); + } + + [OneTimeSetUp] + public void Init() + { + var connectionString = ConfigurationManager.ConnectionStrings["MongoDbTests"].ConnectionString; + SUT = new TestRepository(connectionString, "MongoDbTests"); + } + + [OneTimeTearDown] + public void Cleanup() + { + // We drop the collection at the end of each test session. + if (!string.IsNullOrEmpty(PartitionKey)) + { + SUT.DropTestCollection(PartitionKey); + } + else + { + SUT.DropTestCollection(); + } + } + + #region Add + + [Test] + public void AddOne() + { + // Arrange + var document = new T(); + // Act + SUT.AddOne(document); + // Assert + long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count(e => e.Id.Equals(document.Id)) + : SUT.Count(e => e.Id.Equals(document.Id), PartitionKey); + Assert.AreEqual(1, count, GetTestName()); + } + + [Test] + public async Task AddOneAsync() + { + // Arrange + var document = new T(); + // Act + await SUT.AddOneAsync(document); + // Assert + long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count(e => e.Id.Equals(document.Id)) + : SUT.Count(e => e.Id.Equals(document.Id), PartitionKey); + Assert.AreEqual(1, count, GetTestName()); + } + + [Test] + public void AddMany() + { + // Arrange + var documents = new List { new T(), new T() }; + // Act + SUT.AddMany(documents); + // Assert + long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count(e => e.Id.Equals(documents[0].Id) + || e.Id.Equals(documents[1].Id)) + : SUT.Count(e => e.Id.Equals(documents[0].Id) + || e.Id.Equals(documents[1].Id), PartitionKey); + Assert.AreEqual(2, count, GetTestName()); + } + + [Test] + public async Task AddManyAsync() + { + // Arrange + var documents = new List { new T(), new T() }; + // Act + await SUT.AddManyAsync(documents); + // Assert + long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count(e => e.Id.Equals(documents[0].Id) + || e.Id.Equals(documents[1].Id)) + : SUT.Count(e => e.Id.Equals(documents[0].Id) + || e.Id.Equals(documents[1].Id), PartitionKey); + Assert.AreEqual(2, count, GetTestName()); + } + + + #endregion Add + + #region Read + + [Test] + public async Task GetByIdAsync() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = await SUT.GetByIdAsync(document.Id, PartitionKey); + // Assert + Assert.IsNotNull(result, GetTestName()); + } + + [Test] + public void GetById() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = SUT.GetById(document.Id, PartitionKey); + // Assert + Assert.IsNotNull(result, GetTestName()); + } + + [Test] + public async Task GetOneAsync() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = await SUT.GetOneAsync(x => x.Id.Equals(document.Id), PartitionKey); + // Assert + Assert.IsNotNull(result, GetTestName()); + } + + [Test] + public void GetOne() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = SUT.GetOne(x => x.Id.Equals(document.Id), PartitionKey); + // Assert + Assert.IsNotNull(result, GetTestName()); + } + + [Test] + public void GetCursor() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var cursor = SUT.GetCursor(x => x.Id.Equals(document.Id), PartitionKey); + var count = cursor.Count(); + // Assert + Assert.AreEqual(1, count, GetTestName()); + } + + [Test] + public async Task AnyAsyncReturnsTrue() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = await SUT.AnyAsync(x => x.Id.Equals(document.Id), PartitionKey); + // Assert + Assert.AreEqual(true, result, GetTestName()); + } + + [Test] + public async Task AnyAsyncReturnsFalse() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = await SUT.AnyAsync(x => x.Id.Equals(Guid.NewGuid()), PartitionKey); + // Assert + Assert.AreEqual(false, result, GetTestName()); + } + + [Test] + public void AnyReturnsTrue() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = SUT.Any(x => x.Id.Equals(document.Id), PartitionKey); + // Assert + Assert.AreEqual(true, result, GetTestName()); + } + + [Test] + public void AnyReturnsFalse() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = SUT.Any(x => x.Id.Equals(Guid.NewGuid()), PartitionKey); + // Assert + Assert.AreEqual(false, result, GetTestName()); + } + + [Test] + public async Task GetAllAsync() + { + // Arrange + var documents = CreateTestDocuments(5); + var content = GetContent(); + documents.ForEach(e => e.SomeContent = content); + SUT.AddMany(documents); + // Act + var result = await SUT.GetAllAsync(x => x.SomeContent == content, PartitionKey); + // Assert + Assert.AreEqual(5, result.Count, GetTestName()); + } + + [Test] + public void GetAll() + { + // Arrange + var documents = CreateTestDocuments(5); + var content = GetContent(); + documents.ForEach(e => e.SomeContent = content); + SUT.AddMany(documents); + // Act + var result = SUT.GetAll(x => x.SomeContent == content, PartitionKey); + // Assert + Assert.AreEqual(5, result.Count, GetTestName()); + } + + [Test] + public async Task CountAsync() + { + // Arrange + var documents = CreateTestDocuments(5); + var content = GetContent(); + documents.ForEach(e => e.SomeContent = content); + SUT.AddMany(documents); + // Act + var result = await SUT.CountAsync(x => x.SomeContent == content, PartitionKey); + // Assert + Assert.AreEqual(5, result, GetTestName()); + } + + [Test] + public void Count() + { + // Arrange + var documents = CreateTestDocuments(5); + var content = GetContent(); + documents.ForEach(e => e.SomeContent = content); + SUT.AddMany(documents); + // Act + var result = SUT.Count(x => x.SomeContent == content, PartitionKey); + // Assert + Assert.AreEqual(5, result, GetTestName()); + } + + #endregion Read + + #region Update + + [Test] + public void UpdateOne() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var content = GetContent(); + document.SomeContent = content; + // Act + var result = SUT.UpdateOne(document); + // Assert + Assert.IsTrue(result); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument, GetTestName()); + Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName()); + } + + [Test] + public async Task UpdateOneAsync() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var content = GetContent(); + document.SomeContent = content; + // Act + var result = await SUT.UpdateOneAsync(document); + // Assert + Assert.IsTrue(result); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument, GetTestName()); + Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName()); + } + + [Test] + public void UpdateOneField() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var content = GetContent(); + // Act + var result = SUT.UpdateOne(document, x => x.SomeContent, content); + // Assert + Assert.IsTrue(result, GetTestName()); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument, GetTestName()); + Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName()); + } + + [Test] + public async Task UpdateOneFieldAsync() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var content = GetContent(); + // Act + var result = await SUT.UpdateOneAsync(document, x => x.SomeContent, content); + // Assert + Assert.IsTrue(result, GetTestName()); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument, GetTestName()); + Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName()); + } + + [Test] + public void UpdateOneFieldWithFilter() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var content = GetContent(); + // Act + var result = SUT.UpdateOne(x => x.Id.Equals(document.Id), x => x.SomeContent, content, PartitionKey); + // Assert + Assert.IsTrue(result, GetTestName()); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument, GetTestName()); + Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName()); + } + + [Test] + public async Task UpdateOneFieldWithFilterAsync() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var content = GetContent(); + // Act + var result = await SUT.UpdateOneAsync(x => x.Id.Equals(document.Id), x => x.SomeContent, content, PartitionKey); + // Assert + Assert.IsTrue(result, GetTestName()); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument, GetTestName()); + Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName()); + } + + [Test] + public async Task UpdateOneAsyncWithUpdateDefinition() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var childrenToAdd = new List + { + new Child("testType1", "testValue1"), + new Child("testType2", "testValue2") + }; + + var updateDef = MongoDB.Driver.Builders.Update.AddToSetEach(p => p.Children, childrenToAdd); + + // Act + var result = await SUT.UpdateOneAsync(document, updateDef); + // Assert + Assert.IsTrue(result); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument); + Assert.AreEqual(childrenToAdd[0].Type, updatedDocument.Children[0].Type, GetTestName()); + Assert.AreEqual(childrenToAdd[0].Value, updatedDocument.Children[0].Value, GetTestName()); + Assert.AreEqual(childrenToAdd[1].Type, updatedDocument.Children[1].Type, GetTestName()); + Assert.AreEqual(childrenToAdd[1].Value, updatedDocument.Children[1].Value, GetTestName()); + } + + [Test] + public void UpdateOneWithUpdateDefinition() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var childrenToAdd = new List + { + new Child("testType1", "testValue1"), + new Child("testType2", "testValue2") + }; + + var updateDef = MongoDB.Driver.Builders.Update.AddToSetEach(p => p.Children, childrenToAdd); + + // Act + var result = SUT.UpdateOne(document, updateDef); + // Assert + Assert.IsTrue(result); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument); + Assert.AreEqual(childrenToAdd[0].Type, updatedDocument.Children[0].Type, GetTestName()); + Assert.AreEqual(childrenToAdd[0].Value, updatedDocument.Children[0].Value, GetTestName()); + Assert.AreEqual(childrenToAdd[1].Type, updatedDocument.Children[1].Type, GetTestName()); + Assert.AreEqual(childrenToAdd[1].Value, updatedDocument.Children[1].Value, GetTestName()); + } + + #endregion Update + + #region Delete + + [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.Equals(document.Id), PartitionKey), GetTestName()); + } + + [Test] + public void DeleteOneLinq() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = SUT.DeleteOne(e => e.Id.Equals(document.Id), PartitionKey); + // Assert + Assert.AreEqual(1, result); + Assert.IsFalse(SUT.Any(e => e.Id.Equals(document.Id), PartitionKey), GetTestName()); + } + + [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.Equals(document.Id), PartitionKey), GetTestName()); + } + + [Test] + public async Task DeleteOneAsyncLinq() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + // Act + var result = await SUT.DeleteOneAsync(e => e.Id.Equals(document.Id), PartitionKey); + // Assert + Assert.AreEqual(1, result); + Assert.IsFalse(SUT.Any(e => e.Id.Equals(document.Id), PartitionKey), GetTestName()); + } + + [Test] + public async Task DeleteManyAsyncLinq() + { + // Arrange + var criteria = $"{GetTestName()}.{DocumentTypeName}"; + var documents = CreateTestDocuments(5); + documents.ForEach(e => e.SomeContent = criteria); + SUT.AddMany(documents); + // Act + var result = await SUT.DeleteManyAsync(e => e.SomeContent == criteria, PartitionKey); + // Assert + Assert.AreEqual(5, result); + Assert.IsFalse(SUT.Any(e => e.SomeContent == criteria, PartitionKey), GetTestName()); + } + + [Test] + public async Task DeleteManyAsync() + { + // Arrange + var criteria = $"{GetTestName()}.{DocumentTypeName}"; + var documents = CreateTestDocuments(5); + documents.ForEach(e => e.SomeContent = criteria); + SUT.AddMany(documents); + // Act + var result = await SUT.DeleteManyAsync(documents); + // Assert + Assert.AreEqual(5, result); + Assert.IsFalse(SUT.Any(e => e.SomeContent == criteria, PartitionKey), GetTestName()); + } + + [Test] + public void DeleteManyLinq() + { + // Arrange + var criteria = $"{GetTestName()}.{DocumentTypeName}"; + var documents = CreateTestDocuments(5); + documents.ForEach(e => e.SomeContent = criteria); + SUT.AddMany(documents); + // Act + var result = SUT.DeleteMany(e => e.SomeContent == criteria, PartitionKey); + // Assert + Assert.AreEqual(5, result); + Assert.IsFalse(SUT.Any(e => e.SomeContent == criteria, PartitionKey), GetTestName()); + } + + [Test] + public void DeleteMany() + { + // Arrange + var criteria = $"{GetTestName()}.{DocumentTypeName}"; + var documents = CreateTestDocuments(5); + documents.ForEach(e => e.SomeContent = criteria); + SUT.AddMany(documents); + // Act + var result = SUT.DeleteMany(documents); + // Assert + Assert.AreEqual(5, result); + Assert.IsFalse(SUT.Any(e => e.SomeContent == criteria, PartitionKey), GetTestName()); + } + + #endregion Delete + + #region Project + + [Test] + public async Task ProjectOneAsync() + { + // Arrange + var someContent = GetContent(); + var someDate = DateTime.UtcNow; + var document = CreateTestDocument(); + document.SomeContent = someContent; + document.Nested.SomeDate = someDate; + SUT.AddOne(document); + // Act + var result = await SUT.ProjectOneAsync( + x => x.Id.Equals(document.Id), + x => new MyTestProjection + { + SomeContent = x.SomeContent, + SomeDate = x.Nested.SomeDate + }, + PartitionKey); + // Assert + Assert.IsNotNull(result, GetTestName()); + Assert.AreEqual(someContent, result.SomeContent, GetTestName()); + Assert.AreEqual(someDate.Minute, result.SomeDate.Minute, GetTestName()); + Assert.AreEqual(someDate.Second, result.SomeDate.Second, GetTestName()); + } + + [Test] + public void ProjectOne() + { + // Arrange + var someContent = GetContent(); + var someDate = DateTime.UtcNow; + var document = CreateTestDocument(); + document.SomeContent = someContent; + document.Nested.SomeDate = someDate; + SUT.AddOne(document); + // Act + var result = SUT.ProjectOne( + x => x.Id.Equals(document.Id), + x => new MyTestProjection + { + SomeContent = x.SomeContent, + SomeDate = x.Nested.SomeDate + }, + PartitionKey); + // Assert + Assert.IsNotNull(result, GetTestName()); + Assert.AreEqual(someContent, result.SomeContent, GetTestName()); + Assert.AreEqual(someDate.Minute, result.SomeDate.Minute, GetTestName()); + Assert.AreEqual(someDate.Second, result.SomeDate.Second, GetTestName()); + } + + [Test] + public async Task ProjectManyAsync() + { + // Arrange + var someContent = GetContent(); + var someDate = DateTime.UtcNow; + var documents = CreateTestDocuments(5); + documents.ForEach(e => + { + e.SomeContent = someContent; + e.Nested.SomeDate = someDate; + }); + + SUT.AddMany(documents); + // Act + var result = await SUT.ProjectManyAsync( + x => x.SomeContent == someContent, + x => new MyTestProjection + { + SomeContent = x.SomeContent, + SomeDate = x.Nested.SomeDate + }, + PartitionKey); + // Assert + Assert.AreEqual(5, result.Count, GetTestName()); + Assert.AreEqual(someContent, result.First().SomeContent, GetTestName()); + Assert.AreEqual(someDate.Minute, result.First().SomeDate.Minute, GetTestName()); + Assert.AreEqual(someDate.Second, result.First().SomeDate.Second, GetTestName()); + } + + [Test] + public void ProjectMany() + { + // Arrange + var someContent = GetContent(); + var someDate = DateTime.UtcNow; + var documents = CreateTestDocuments(5); + documents.ForEach(e => + { + e.SomeContent = someContent; + e.Nested.SomeDate = someDate; + }); + + SUT.AddMany(documents); + // Act + var result = SUT.ProjectMany( + x => x.SomeContent == someContent, + x => new MyTestProjection + { + SomeContent = x.SomeContent, + SomeDate = x.Nested.SomeDate + }, + PartitionKey); + // Assert + Assert.AreEqual(5, result.Count, GetTestName()); + Assert.AreEqual(someContent, result.First().SomeContent, GetTestName()); + Assert.AreEqual(someDate.Minute, result.First().SomeDate.Minute, GetTestName()); + Assert.AreEqual(someDate.Second, result.First().SomeDate.Second, GetTestName()); + } + + #endregion Project + + #region Test Utils + [MethodImpl(MethodImplOptions.NoInlining)] + private string GetCurrentMethod() + { + StackTrace st = new StackTrace(); + StackFrame sf = st.GetFrame(1); + + return sf.GetMethod().Name; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private string GetParentMethod() + { + StackTrace st = new StackTrace(); + StackFrame sf = st.GetFrame(2); + var method = sf.GetMethod().DeclaringType.Name; + return method; + } + + private string GetTestName() + { + return $"{TestClassName}{PartitionKey}.{GetParentMethod()}"; + } + + private string GetContent() + { + return $"{TestClassName}{PartitionKey}.{Guid.NewGuid()}.{GetParentMethod()}"; + } + + #endregion Test Utils + } +} diff --git a/IntegrationTests/Infrastructure/MongoDBTestBase.cs b/IntegrationTests/Infrastructure/MongoDbTKeyDocumentTestBase.cs similarity index 76% rename from IntegrationTests/Infrastructure/MongoDBTestBase.cs rename to IntegrationTests/Infrastructure/MongoDbTKeyDocumentTestBase.cs index be2ca7d..01605b5 100644 --- a/IntegrationTests/Infrastructure/MongoDBTestBase.cs +++ b/IntegrationTests/Infrastructure/MongoDbTKeyDocumentTestBase.cs @@ -26,12 +26,15 @@ namespace IntegrationTests.Infrastructure { SomeDate = DateTime.UtcNow }; + Children = new List(); } public string SomeContent { get; set; } public Nested Nested { get; set; } + public List Children { get; set; } + public TId Init() { var idTypeName = typeof(TKey).Name; @@ -60,7 +63,7 @@ namespace IntegrationTests.Infrastructure [TestFixture] - public abstract class MongoDBTestBase + public abstract class MongoDbTKeyDocumentTestBase where T: TestDoc, new() where TKey : IEquatable { @@ -101,7 +104,7 @@ namespace IntegrationTests.Infrastructure /// protected static ITestRepository SUT { get; set; } - public MongoDBTestBase() + public MongoDbTKeyDocumentTestBase() { var type = CreateTestDocument(); DocumentTypeName = type.GetType().FullName; @@ -220,9 +223,8 @@ namespace IntegrationTests.Infrastructure Assert.IsNotNull(result, GetTestName()); } - [Test] - public async Task PartitionedGetOneAsync() + public async Task GetOneAsync() { // Arrange var document = CreateTestDocument(); @@ -359,11 +361,165 @@ namespace IntegrationTests.Infrastructure // Act var result = SUT.Count(x => x.SomeContent == content, PartitionKey); // Assert - Assert.AreEqual(5, result); + Assert.AreEqual(5, result, GetTestName()); } #endregion Read + #region Update + + [Test] + public void UpdateOne() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var content = GetContent(); + document.SomeContent = content; + // Act + var result = SUT.UpdateOne(document); + // Assert + Assert.IsTrue(result); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument, GetTestName()); + Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName()); + } + + [Test] + public async Task UpdateOneAsync() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var content = GetContent(); + document.SomeContent = content; + // Act + var result = await SUT.UpdateOneAsync(document); + // Assert + Assert.IsTrue(result); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument, GetTestName()); + Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName()); + } + + [Test] + public void UpdateOneField() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var content = GetContent(); + // Act + var result = SUT.UpdateOne(document, x => x.SomeContent, content); + // Assert + Assert.IsTrue(result, GetTestName()); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument, GetTestName()); + Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName()); + } + + [Test] + public async Task UpdateOneFieldAsync() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var content = GetContent(); + // Act + var result = await SUT.UpdateOneAsync(document, x => x.SomeContent, content); + // Assert + Assert.IsTrue(result, GetTestName()); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument, GetTestName()); + Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName()); + } + + [Test] + public void UpdateOneFieldWithFilter() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var content = GetContent(); + // Act + var result = SUT.UpdateOne(x => x.Id.Equals(document.Id), x => x.SomeContent, content, PartitionKey); + // Assert + Assert.IsTrue(result, GetTestName()); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument, GetTestName()); + Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName()); + } + + [Test] + public async Task UpdateOneFieldWithFilterAsync() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var content = GetContent(); + // Act + var result = await SUT.UpdateOneAsync(x => x.Id.Equals(document.Id), x => x.SomeContent, content, PartitionKey); + // Assert + Assert.IsTrue(result, GetTestName()); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument, GetTestName()); + Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName()); + } + + [Test] + public async Task UpdateOneAsyncWithUpdateDefinition() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var childrenToAdd = new List + { + new Child("testType1", "testValue1"), + new Child("testType2", "testValue2") + }; + + var updateDef = MongoDB.Driver.Builders.Update.AddToSetEach(p => p.Children, childrenToAdd); + + // Act + var result = await SUT.UpdateOneAsync(document, updateDef); + // Assert + Assert.IsTrue(result); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument); + Assert.AreEqual(childrenToAdd[0].Type, updatedDocument.Children[0].Type, GetTestName()); + Assert.AreEqual(childrenToAdd[0].Value, updatedDocument.Children[0].Value, GetTestName()); + Assert.AreEqual(childrenToAdd[1].Type, updatedDocument.Children[1].Type, GetTestName()); + Assert.AreEqual(childrenToAdd[1].Value, updatedDocument.Children[1].Value, GetTestName()); + } + + [Test] + public void UpdateOneWithUpdateDefinition() + { + // Arrange + var document = CreateTestDocument(); + SUT.AddOne(document); + var childrenToAdd = new List + { + new Child("testType1", "testValue1"), + new Child("testType2", "testValue2") + }; + + var updateDef = MongoDB.Driver.Builders.Update.AddToSetEach(p => p.Children, childrenToAdd); + + // Act + var result = SUT.UpdateOne(document, updateDef); + // Assert + Assert.IsTrue(result); + var updatedDocument = SUT.GetById(document.Id, PartitionKey); + Assert.IsNotNull(updatedDocument); + Assert.AreEqual(childrenToAdd[0].Type, updatedDocument.Children[0].Type, GetTestName()); + Assert.AreEqual(childrenToAdd[0].Value, updatedDocument.Children[0].Value, GetTestName()); + Assert.AreEqual(childrenToAdd[1].Type, updatedDocument.Children[1].Type, GetTestName()); + Assert.AreEqual(childrenToAdd[1].Value, updatedDocument.Children[1].Value, GetTestName()); + } + + #endregion Update + #region Delete [Test] diff --git a/IntegrationTests/IntegrationTests.csproj b/IntegrationTests/IntegrationTests.csproj index d1f40cd..0897336 100644 --- a/IntegrationTests/IntegrationTests.csproj +++ b/IntegrationTests/IntegrationTests.csproj @@ -48,8 +48,11 @@ - + + + + @@ -59,7 +62,8 @@ - + + @@ -68,9 +72,7 @@ - - diff --git a/IntegrationTests/UpdatePartitionedTKeyTests.cs b/IntegrationTests/UpdatePartitionedTKeyTests.cs deleted file mode 100644 index 41c66cf..0000000 --- a/IntegrationTests/UpdatePartitionedTKeyTests.cs +++ /dev/null @@ -1,117 +0,0 @@ -using IntegrationTests.Infrastructure; -using MongoDB.Bson.Serialization.Attributes; -using MongoDB.Driver; -using MongoDbGenericRepository.Models; -using NUnit.Framework; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace IntegrationTests -{ - - public class UpdateTestsPartitionedTKeyDocument : IDocument, IPartitionedDocument - { - [BsonId] - public Guid Id { get; set; } - public int Version { get; set; } - public UpdateTestsPartitionedTKeyDocument() - { - Id = Guid.NewGuid(); - Version = 2; - PartitionKey = "TestPartitionKey"; - Children = new List(); - } - public string PartitionKey { get; set; } - public string SomeContent { get; set; } - public List Children { get; set; } - } - - [TestFixture] - public class UpdatePartitionedTKeyTests : BaseMongoDbRepositoryTests - { - [Test] - public void PartitionedUpdateOne() - { - // Arrange - var document = CreateTestDocument(); - SUT.AddOne(document); - document.SomeContent = "UpdateOneContent"; - // Act - var result = SUT.UpdateOne(document); - // Assert - Assert.IsTrue(result); - var updatedDocument = SUT.GetById(document.Id, PartitionKey); - Assert.IsNotNull(updatedDocument); - Assert.AreEqual("UpdateOneContent", updatedDocument.SomeContent); - } - - [Test] - public async Task PartitionedUpdateOneAsync() - { - // Arrange - var document = CreateTestDocument(); - SUT.AddOne(document); - document.SomeContent = "UpdateOneAsyncContent"; - // Act - var result = await SUT.UpdateOneAsync(document); - // Assert - Assert.IsTrue(result); - var updatedDocument = SUT.GetById(document.Id, PartitionKey); - Assert.IsNotNull(updatedDocument); - Assert.AreEqual("UpdateOneAsyncContent", updatedDocument.SomeContent); - } - - [Test] - public async Task UpdateOneAsyncWithUpdateDefinition() - { - // Arrange - var document = CreateTestDocument(); - SUT.AddOne(document); - var childrenToAdd = new List - { - new Child("testType1", "testValue1"), - new Child("testType2", "testValue2") - }; - - var updateDef = Builders.Update.AddToSetEach(p => p.Children, childrenToAdd); - - // Act - var result = await SUT.UpdateOneAsync(document, updateDef); - // Assert - Assert.IsTrue(result); - var updatedDocument = SUT.GetById(document.Id, document.PartitionKey); - Assert.IsNotNull(updatedDocument); - Assert.AreEqual(childrenToAdd[0].Type, updatedDocument.Children[0].Type); - Assert.AreEqual(childrenToAdd[0].Value, updatedDocument.Children[0].Value); - Assert.AreEqual(childrenToAdd[1].Type, updatedDocument.Children[1].Type); - Assert.AreEqual(childrenToAdd[1].Value, updatedDocument.Children[1].Value); - } - - [Test] - public void UpdateOneWithUpdateDefinition() - { - // Arrange - var document = CreateTestDocument(); - SUT.AddOne(document); - var childrenToAdd = new List - { - new Child("testType1", "testValue1"), - new Child("testType2", "testValue2") - }; - - var updateDef = Builders.Update.AddToSetEach(p => p.Children, childrenToAdd); - - // Act - var result = SUT.UpdateOne(document, updateDef); - // Assert - Assert.IsTrue(result); - var updatedDocument = SUT.GetById(document.Id, document.PartitionKey); - Assert.IsNotNull(updatedDocument); - Assert.AreEqual(childrenToAdd[0].Type, updatedDocument.Children[0].Type); - Assert.AreEqual(childrenToAdd[0].Value, updatedDocument.Children[0].Value); - Assert.AreEqual(childrenToAdd[1].Type, updatedDocument.Children[1].Type); - Assert.AreEqual(childrenToAdd[1].Value, updatedDocument.Children[1].Value); - } - } -} diff --git a/IntegrationTests/UpdateTKeyTests.cs b/IntegrationTests/UpdateTKeyTests.cs deleted file mode 100644 index f981196..0000000 --- a/IntegrationTests/UpdateTKeyTests.cs +++ /dev/null @@ -1,195 +0,0 @@ -using IntegrationTests.Infrastructure; -using MongoDB.Bson.Serialization.Attributes; -using MongoDB.Driver; -using MongoDbGenericRepository.Models; -using NUnit.Framework; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace IntegrationTests -{ - - public class UpdateTestsTKeyDocument : IDocument - { - [BsonId] - public Guid Id { get; set; } - public int Version { get; set; } - public UpdateTestsTKeyDocument() - { - Id = Guid.NewGuid(); - Version = 2; - Children = new List(); - } - public string SomeContent { get; set; } - public List Children { get; set; } - } - - [TestFixture] - public class UpdateTKeyTests : BaseMongoDbRepositoryTests - { - [Test] - public void UpdateOne() - { - // Arrange - var document = CreateTestDocument(); - SUT.AddOne(document); - document.SomeContent = "UpdateOneContent"; - // Act - var result = SUT.UpdateOne(document); - // Assert - Assert.IsTrue(result); - var updatedDocument = SUT.GetById(document.Id); - Assert.IsNotNull(updatedDocument); - Assert.AreEqual("UpdateOneContent", updatedDocument.SomeContent); - } - - [Test] - public async Task UpdateOneAsync() - { - // Arrange - var document = CreateTestDocument(); - SUT.AddOne(document); - document.SomeContent = "UpdateOneAsyncContent"; - // Act - var result = await SUT.UpdateOneAsync(document); - // Assert - Assert.IsTrue(result); - var updatedDocument = SUT.GetById(document.Id); - Assert.IsNotNull(updatedDocument); - Assert.AreEqual("UpdateOneAsyncContent", updatedDocument.SomeContent); - } - - [Test] - public async Task UpdateOneAsyncWithUpdateDefinition() - { - // Arrange - var document = CreateTestDocument(); - SUT.AddOne(document); - var childrenToAdd = new List - { - new Child("testType1", "testValue1"), - new Child("testType2", "testValue2") - }; - - var updateDef = Builders.Update.AddToSetEach(p => p.Children, childrenToAdd); - // Act - var result = await SUT.UpdateOneAsync(document, updateDef); - // Assert - Assert.IsTrue(result); - var updatedDocument = SUT.GetById(document.Id); - Assert.IsNotNull(updatedDocument); - Assert.AreEqual(childrenToAdd[0].Type, updatedDocument.Children[0].Type); - Assert.AreEqual(childrenToAdd[0].Value, updatedDocument.Children[0].Value); - Assert.AreEqual(childrenToAdd[1].Type, updatedDocument.Children[1].Type); - Assert.AreEqual(childrenToAdd[1].Value, updatedDocument.Children[1].Value); - } - - [Test] - public void UpdateOneWithUpdateDefinition() - { - // Arrange - var document = CreateTestDocument(); - SUT.AddOne(document); - var childrenToAdd = new List - { - new Child("testType1", "testValue1"), - new Child("testType2", "testValue2") - }; - - var updateDef = Builders.Update.AddToSetEach(p => p.Children, childrenToAdd); - - // Act - var result = SUT.UpdateOne(document, updateDef); - // Assert - Assert.IsTrue(result); - var updatedDocument = SUT.GetById(document.Id); - Assert.IsNotNull(updatedDocument); - Assert.AreEqual(childrenToAdd[0].Type, updatedDocument.Children[0].Type); - Assert.AreEqual(childrenToAdd[0].Value, updatedDocument.Children[0].Value); - Assert.AreEqual(childrenToAdd[1].Type, updatedDocument.Children[1].Type); - Assert.AreEqual(childrenToAdd[1].Value, updatedDocument.Children[1].Value); - } - - [Test] - public void UpdateOneWithFieldSelector() - { - // Arrange - var document = CreateTestDocument(); - SUT.AddOne(document); - - var childrenToAdd = new List - { - new Child("testType1", "testValue1"), - new Child("testType2", "testValue2") - }; - - var filter = Builders.Filter.Eq("Id", document.Id); - - // Act - var result = SUT.UpdateOne>(document, x => x.Children, childrenToAdd); - // Assert - Assert.IsTrue(result); - var updatedDocument = SUT.GetById(document.Id); - Assert.IsNotNull(updatedDocument); - Assert.AreEqual(childrenToAdd[0].Type, updatedDocument.Children[0].Type); - Assert.AreEqual(childrenToAdd[0].Value, updatedDocument.Children[0].Value); - Assert.AreEqual(childrenToAdd[1].Type, updatedDocument.Children[1].Type); - Assert.AreEqual(childrenToAdd[1].Value, updatedDocument.Children[1].Value); - } - - [Test] - public async Task UpdateOneAsyncWithFieldSelector() - { - // Arrange - var document = CreateTestDocument(); - SUT.AddOne(document); - - var childrenToAdd = new List - { - new Child("testType1", "testValue1"), - new Child("testType2", "testValue2") - }; - - var filter = Builders.Filter.Eq("Id", document.Id); - - // Act - var result = await SUT.UpdateOneAsync>(document, x => x.Children, childrenToAdd); - // Assert - Assert.IsTrue(result); - var updatedDocument = SUT.GetById(document.Id); - Assert.IsNotNull(updatedDocument); - Assert.AreEqual(childrenToAdd[0].Type, updatedDocument.Children[0].Type); - Assert.AreEqual(childrenToAdd[0].Value, updatedDocument.Children[0].Value); - Assert.AreEqual(childrenToAdd[1].Type, updatedDocument.Children[1].Type); - Assert.AreEqual(childrenToAdd[1].Value, updatedDocument.Children[1].Value); - } - - [Test] - public void UpdateOneWithFilterAndFieldSelector() - { - // Arrange - var document = CreateTestDocument(); - SUT.AddOne(document); - - var childrenToAdd = new List - { - new Child("testType1", "testValue1"), - new Child("testType2", "testValue2") - }; - - var filter = Builders.Filter.Eq("Id", document.Id); - - // Act - var result = SUT.UpdateOne>(filter, x => x.Children, childrenToAdd); - // Assert - Assert.IsTrue(result); - var updatedDocument = SUT.GetById(document.Id); - Assert.IsNotNull(updatedDocument); - Assert.AreEqual(childrenToAdd[0].Type, updatedDocument.Children[0].Type); - Assert.AreEqual(childrenToAdd[0].Value, updatedDocument.Children[0].Value); - Assert.AreEqual(childrenToAdd[1].Type, updatedDocument.Children[1].Type); - Assert.AreEqual(childrenToAdd[1].Value, updatedDocument.Children[1].Value); - } - } -} diff --git a/MongoDbGenericRepository/Abstractions/IBaseMongoRepository.cs b/MongoDbGenericRepository/Abstractions/IBaseMongoRepository.cs index df216da..23548be 100644 --- a/MongoDbGenericRepository/Abstractions/IBaseMongoRepository.cs +++ b/MongoDbGenericRepository/Abstractions/IBaseMongoRepository.cs @@ -159,6 +159,18 @@ namespace MongoDbGenericRepository Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) where TDocument : IDocument; + /// + /// For the entity selected by the filter, updates the property field with the given value. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument; + /// /// Takes a document you want to modify and applies the update you have defined in MongoDb. /// @@ -168,6 +180,18 @@ namespace MongoDbGenericRepository Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) where TDocument : IDocument; + /// + /// For the entity selected by the filter, updates the property field with the given value. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument; + /// /// Takes a document you want to modify and applies the update you have defined in MongoDb. /// @@ -223,6 +247,19 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable; + /// + /// For the entity selected by the filter, updates the property field with the given value.. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + /// /// Updates the property field with the given value update a property field in entities. /// @@ -236,6 +273,19 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable; + /// + /// For the entity selected by the filter, updates the property field with the given value. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + /// /// Updates the property field with the given value update a property field in entities. /// diff --git a/MongoDbGenericRepository/Abstractions/IMongoDbContext.cs b/MongoDbGenericRepository/Abstractions/IMongoDbContext.cs index f3497fc..2af5eb1 100644 --- a/MongoDbGenericRepository/Abstractions/IMongoDbContext.cs +++ b/MongoDbGenericRepository/Abstractions/IMongoDbContext.cs @@ -19,18 +19,12 @@ namespace MongoDbGenericRepository /// IMongoDatabase Database { get; } - /// - /// The private GetCollection method - /// - /// - IMongoCollection GetCollection(); - /// /// Returns a collection for a document type that has a partition key. /// /// /// The value of the partition key. - IMongoCollection GetCollection(string partitionKey) where TDocument : IDocument; + IMongoCollection GetCollection(string partitionKey = null) where TDocument : IDocument; /// /// Returns a collection for a document type that has a partition key. @@ -38,7 +32,7 @@ namespace MongoDbGenericRepository /// The type representing a Document. /// The type of the primary key for a Document. /// The value of the partition key. - IMongoCollection GetCollection(string partitionKey) + IMongoCollection GetCollection(string partitionKey = null) where TDocument : IDocument where TKey : IEquatable; diff --git a/MongoDbGenericRepository/BaseMongoDbRepository.cs b/MongoDbGenericRepository/BaseMongoDbRepository.cs index df2bf6b..77ab063 100644 --- a/MongoDbGenericRepository/BaseMongoDbRepository.cs +++ b/MongoDbGenericRepository/BaseMongoDbRepository.cs @@ -53,7 +53,7 @@ namespace MongoDbGenericRepository /// /// The type representing a Document. /// The document you want to add. - public async Task AddOneAsync(TDocument document) where TDocument : IDocument + public virtual async Task AddOneAsync(TDocument document) where TDocument : IDocument { FormatDocument(document); await HandlePartitioned(document).InsertOneAsync(document); @@ -65,7 +65,7 @@ namespace MongoDbGenericRepository /// /// The type representing a Document. /// The document you want to add. - public void AddOne(TDocument document) where TDocument : IDocument + public virtual void AddOne(TDocument document) where TDocument : IDocument { FormatDocument(document); HandlePartitioned(document).InsertOne(document); @@ -77,7 +77,7 @@ namespace MongoDbGenericRepository /// /// The type representing a Document. /// The documents you want to add. - public async Task AddManyAsync(IEnumerable documents) where TDocument : IDocument + public virtual async Task AddManyAsync(IEnumerable documents) where TDocument : IDocument { if (!documents.Any()) { @@ -96,7 +96,7 @@ namespace MongoDbGenericRepository /// /// The type representing a Document. /// The documents you want to add. - public void AddMany(IEnumerable documents) where TDocument : IDocument + public virtual void AddMany(IEnumerable documents) where TDocument : IDocument { if (!documents.Any()) { @@ -120,7 +120,7 @@ namespace MongoDbGenericRepository /// The type representing a Document. /// The type of the primary key for a Document. /// The document you want to add. - public async Task AddOneAsync(TDocument document) + public virtual async Task AddOneAsync(TDocument document) where TDocument : IDocument where TKey : IEquatable { @@ -135,7 +135,7 @@ namespace MongoDbGenericRepository /// The type representing a Document. /// The type of the primary key for a Document. /// The document you want to add. - public void AddOne(TDocument document) + public virtual void AddOne(TDocument document) where TDocument : IDocument where TKey : IEquatable { @@ -150,7 +150,7 @@ namespace MongoDbGenericRepository /// The type representing a Document. /// The type of the primary key for a Document. /// The documents you want to add. - public async Task AddManyAsync(IEnumerable documents) + public virtual async Task AddManyAsync(IEnumerable documents) where TDocument : IDocument where TKey : IEquatable { @@ -172,7 +172,7 @@ namespace MongoDbGenericRepository /// The type representing a Document. /// The type of the primary key for a Document. /// The documents you want to add. - public void AddMany(IEnumerable documents) + public virtual void AddMany(IEnumerable documents) where TDocument : IDocument where TKey : IEquatable { @@ -197,7 +197,7 @@ namespace MongoDbGenericRepository /// /// The type representing a Document. /// The document with the modifications you want to persist. - public async Task UpdateOneAsync(TDocument modifiedDocument) where TDocument : IDocument + public virtual async Task UpdateOneAsync(TDocument modifiedDocument) where TDocument : IDocument { var updateRes = await HandlePartitioned(modifiedDocument).ReplaceOneAsync(x => x.Id == modifiedDocument.Id, modifiedDocument); return updateRes.ModifiedCount == 1; @@ -208,7 +208,7 @@ namespace MongoDbGenericRepository /// /// The type representing a Document. /// The document with the modifications you want to persist. - public bool UpdateOne(TDocument modifiedDocument) where TDocument : IDocument + public virtual bool UpdateOne(TDocument modifiedDocument) where TDocument : IDocument { var updateRes = HandlePartitioned(modifiedDocument).ReplaceOne(x => x.Id == modifiedDocument.Id, modifiedDocument); return updateRes.ModifiedCount == 1; @@ -220,7 +220,7 @@ namespace MongoDbGenericRepository /// The type representing a Document. /// The document you want to modify. /// The update definition for the document. - public async Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) + public virtual async Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) where TDocument : IDocument { var filter = Builders.Filter.Eq("Id", documentToModify.Id); @@ -236,7 +236,7 @@ namespace MongoDbGenericRepository /// The document you want to modify. /// The field selector. /// The new value of the property field. - public bool UpdateOne(TDocument documentToModify, Expression> field, TField value) + public virtual bool UpdateOne(TDocument documentToModify, Expression> field, TField value) where TDocument : IDocument { var filter = Builders.Filter.Eq("Id", documentToModify.Id); @@ -252,7 +252,7 @@ namespace MongoDbGenericRepository /// The document you want to modify. /// The field selector. /// The new value of the property field. - public async Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) + public virtual async Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) where TDocument : IDocument { var filter = Builders.Filter.Eq("Id", documentToModify.Id); @@ -269,7 +269,7 @@ namespace MongoDbGenericRepository /// The field selector. /// The new value of the property field. /// The value of the partition key. - public bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + public virtual bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) where TDocument : IDocument { var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); @@ -277,6 +277,23 @@ namespace MongoDbGenericRepository return updateRes.ModifiedCount == 1; } + /// + /// For the entity selected by the filter, updates the property field with the given value. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + public virtual bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + { + var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); + var updateRes = collection.UpdateOne(Builders.Filter.Where(filter), Builders.Update.Set(field, value)); + return updateRes.ModifiedCount == 1; + } + /// /// Updates the property field with the given value update a property field in entities. /// @@ -286,7 +303,7 @@ namespace MongoDbGenericRepository /// The field selector. /// The new value of the property field. /// The value of the partition key. - public async Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + public virtual async Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) where TDocument : IDocument { var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); @@ -294,13 +311,30 @@ namespace MongoDbGenericRepository return updateRes.ModifiedCount == 1; } + /// + /// For the entity selected by the filter, updates the property field with the given value. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + public virtual async Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + { + var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); + var updateRes = await collection.UpdateOneAsync(Builders.Filter.Where(filter), Builders.Update.Set(field, value)); + return updateRes.ModifiedCount == 1; + } + /// /// Takes a document you want to modify and applies the update you have defined in MongoDb. /// /// The type representing a Document. /// The document you want to modify. /// The update definition for the document. - public bool UpdateOne(TDocument documentToModify, UpdateDefinition update) + public virtual bool UpdateOne(TDocument documentToModify, UpdateDefinition update) where TDocument : IDocument { var filter = Builders.Filter.Eq("Id", documentToModify.Id); @@ -318,7 +352,7 @@ namespace MongoDbGenericRepository /// The type representing a Document. /// The type of the primary key for a Document. /// The document with the modifications you want to persist. - public async Task UpdateOneAsync(TDocument modifiedDocument) + public virtual async Task UpdateOneAsync(TDocument modifiedDocument) where TDocument : IDocument where TKey : IEquatable { @@ -333,7 +367,7 @@ namespace MongoDbGenericRepository /// The type representing a Document. /// The type of the primary key for a Document. /// The document with the modifications you want to persist. - public bool UpdateOne(TDocument modifiedDocument) + public virtual bool UpdateOne(TDocument modifiedDocument) where TDocument : IDocument where TKey : IEquatable { @@ -349,7 +383,7 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// The document you want to modify. /// The update definition for the document. - public async Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) + public virtual async Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) where TDocument : IDocument where TKey : IEquatable { @@ -365,7 +399,7 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// The document you want to modify. /// The update definition for the document. - public bool UpdateOne(TDocument documentToModify, UpdateDefinition update) + public virtual bool UpdateOne(TDocument documentToModify, UpdateDefinition update) where TDocument : IDocument where TKey : IEquatable { @@ -383,7 +417,7 @@ namespace MongoDbGenericRepository /// The document you want to modify. /// The field selector. /// The new value of the property field. - public async Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) + public virtual async Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) where TDocument : IDocument where TKey : IEquatable { @@ -401,7 +435,7 @@ namespace MongoDbGenericRepository /// The document you want to modify. /// The field selector. /// The new value of the property field. - public bool UpdateOne(TDocument documentToModify, Expression> field, TField value) + public virtual bool UpdateOne(TDocument documentToModify, Expression> field, TField value) where TDocument : IDocument where TKey : IEquatable { @@ -420,7 +454,7 @@ namespace MongoDbGenericRepository /// The field selector. /// The new value of the property field. /// The value of the partition key. - public async Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + public virtual async Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { @@ -430,7 +464,25 @@ namespace MongoDbGenericRepository } /// - /// Updates the property field with the given value update a property field in entities. + /// For the entity selected by the filter, updates the property field with the given value. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + public virtual async Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); + var updateRes = await collection.UpdateOneAsync(Builders.Filter.Where(filter), Builders.Update.Set(field, value)); + return updateRes.ModifiedCount == 1; + } + + /// + /// Updates the property field with the given value. /// /// The type representing a Document. /// The type of the primary key for a Document. @@ -439,7 +491,7 @@ namespace MongoDbGenericRepository /// The field selector. /// The new value of the property field. /// The value of the partition key. - public bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + public virtual bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { @@ -448,6 +500,24 @@ namespace MongoDbGenericRepository return updateRes.ModifiedCount == 1; } + /// + /// For the entity selected by the filter, updates the property field with the given value. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + public virtual bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); + var updateRes = collection.UpdateOne(Builders.Filter.Where(filter), Builders.Update.Set(field, value)); + return updateRes.ModifiedCount == 1; + } + #endregion Update #region Delete @@ -458,7 +528,7 @@ namespace MongoDbGenericRepository /// The type representing a Document. /// The document you want to delete. /// The number of documents deleted. - public async Task DeleteOneAsync(TDocument document) where TDocument : IDocument + public virtual async Task DeleteOneAsync(TDocument document) where TDocument : IDocument { return (await HandlePartitioned(document).DeleteOneAsync(x => x.Id == document.Id)).DeletedCount; } @@ -469,7 +539,7 @@ namespace MongoDbGenericRepository /// The type representing a Document. /// The document you want to delete. /// The number of documents deleted. - public long DeleteOne(TDocument document) where TDocument : IDocument + public virtual long DeleteOne(TDocument document) where TDocument : IDocument { return HandlePartitioned(document).DeleteOne(x => x.Id == document.Id).DeletedCount; } @@ -481,7 +551,7 @@ namespace MongoDbGenericRepository /// A LINQ expression filter. /// An optional partition key. /// The number of documents deleted. - public long DeleteOne(Expression> filter, string partitionKey = null) where TDocument : IDocument + public virtual long DeleteOne(Expression> filter, string partitionKey = null) where TDocument : IDocument { return HandlePartitioned(partitionKey).DeleteOne(filter).DeletedCount; } @@ -493,7 +563,7 @@ namespace MongoDbGenericRepository /// 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 + public virtual async Task DeleteOneAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument { return (await HandlePartitioned(partitionKey).DeleteOneAsync(filter)).DeletedCount; } @@ -505,7 +575,7 @@ namespace MongoDbGenericRepository /// 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 + public virtual async Task DeleteManyAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument { return (await HandlePartitioned(partitionKey).DeleteManyAsync(filter)).DeletedCount; } @@ -516,7 +586,7 @@ namespace MongoDbGenericRepository /// The type representing a Document. /// The list of documents to delete. /// The number of documents deleted. - public async Task DeleteManyAsync(IEnumerable documents) where TDocument : IDocument + public virtual async Task DeleteManyAsync(IEnumerable documents) where TDocument : IDocument { if (!documents.Any()) { @@ -532,7 +602,7 @@ namespace MongoDbGenericRepository /// The type representing a Document. /// The list of documents to delete. /// The number of documents deleted. - public long DeleteMany(IEnumerable documents) where TDocument : IDocument + public virtual long DeleteMany(IEnumerable documents) where TDocument : IDocument { if (!documents.Any()) { @@ -549,7 +619,7 @@ namespace MongoDbGenericRepository /// A LINQ expression filter. /// An optional partition key. /// The number of documents deleted. - public long DeleteMany(Expression> filter, string partitionKey = null) where TDocument : IDocument + public virtual long DeleteMany(Expression> filter, string partitionKey = null) where TDocument : IDocument { return HandlePartitioned(partitionKey).DeleteMany(filter).DeletedCount; } @@ -565,7 +635,7 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// The document you want to delete. /// The number of documents deleted. - public long DeleteOne(TDocument document) + public virtual long DeleteOne(TDocument document) where TDocument : IDocument where TKey : IEquatable { @@ -580,7 +650,7 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// The document you want to delete. /// The number of documents deleted. - public async Task DeleteOneAsync(TDocument document) + public virtual async Task DeleteOneAsync(TDocument document) where TDocument : IDocument where TKey : IEquatable { @@ -596,7 +666,7 @@ namespace MongoDbGenericRepository /// A LINQ expression filter. /// An optional partition key. /// The number of documents deleted. - public long DeleteOne(Expression> filter, string partitionKey = null) + public virtual long DeleteOne(Expression> filter, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { @@ -611,7 +681,7 @@ namespace MongoDbGenericRepository /// A LINQ expression filter. /// An optional partition key. /// The number of documents deleted. - public async Task DeleteOneAsync(Expression> filter, string partitionKey = null) + public virtual async Task DeleteOneAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { @@ -626,7 +696,7 @@ namespace MongoDbGenericRepository /// A LINQ expression filter. /// An optional partition key. /// The number of documents deleted. - public async Task DeleteManyAsync(Expression> filter, string partitionKey = null) + public virtual async Task DeleteManyAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { @@ -640,7 +710,7 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// The list of documents to delete. /// The number of documents deleted. - public async Task DeleteManyAsync(IEnumerable documents) + public virtual async Task DeleteManyAsync(IEnumerable documents) where TDocument : IDocument where TKey : IEquatable { @@ -659,7 +729,7 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// The list of documents to delete. /// The number of documents deleted. - public long DeleteMany(IEnumerable documents) + public virtual long DeleteMany(IEnumerable documents) where TDocument : IDocument where TKey : IEquatable { @@ -679,7 +749,7 @@ namespace MongoDbGenericRepository /// A LINQ expression filter. /// An optional partition key. /// The number of documents deleted. - public long DeleteMany(Expression> filter, string partitionKey = null) + public virtual long DeleteMany(Expression> filter, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { @@ -698,7 +768,7 @@ namespace MongoDbGenericRepository /// /// The projection expression. /// An optional partition key. - public async Task ProjectOneAsync(Expression> filter, Expression> projection, string partitionKey = null) + public virtual async Task ProjectOneAsync(Expression> filter, Expression> projection, string partitionKey = null) where TDocument : IDocument where TProjection : class { @@ -716,7 +786,7 @@ namespace MongoDbGenericRepository /// /// The projection expression. /// An optional partition key. - public async Task ProjectOneAsync(Expression> filter, Expression> projection, string partitionKey = null) + public virtual async Task ProjectOneAsync(Expression> filter, Expression> projection, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable where TProjection : class @@ -734,7 +804,7 @@ namespace MongoDbGenericRepository /// /// The projection expression. /// An optional partition key. - public TProjection ProjectOne(Expression> filter, Expression> projection, string partitionKey = null) + public virtual TProjection ProjectOne(Expression> filter, Expression> projection, string partitionKey = null) where TDocument : IDocument where TProjection : class { @@ -752,7 +822,7 @@ namespace MongoDbGenericRepository /// /// The projection expression. /// An optional partition key. - public TProjection ProjectOne(Expression> filter, Expression> projection, string partitionKey = null) + public virtual TProjection ProjectOne(Expression> filter, Expression> projection, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable where TProjection : class @@ -770,7 +840,7 @@ namespace MongoDbGenericRepository /// /// The projection expression. /// An optional partition key. - public async Task> ProjectManyAsync(Expression> filter, Expression> projection, string partitionKey = null) + public virtual async Task> ProjectManyAsync(Expression> filter, Expression> projection, string partitionKey = null) where TDocument : IDocument where TProjection : class { @@ -788,7 +858,7 @@ namespace MongoDbGenericRepository /// /// The projection expression. /// An optional partition key. - public async Task> ProjectManyAsync(Expression> filter, Expression> projection, string partitionKey = null) + public virtual async Task> ProjectManyAsync(Expression> filter, Expression> projection, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable where TProjection : class @@ -806,7 +876,7 @@ namespace MongoDbGenericRepository /// /// The projection expression. /// An optional partition key. - public List ProjectMany(Expression> filter, Expression> projection, string partitionKey = null) + public virtual List ProjectMany(Expression> filter, Expression> projection, string partitionKey = null) where TDocument : IDocument where TProjection : class { @@ -824,7 +894,7 @@ namespace MongoDbGenericRepository /// The document filter. /// The projection expression. /// An optional partition key. - public List ProjectMany(Expression> filter, Expression> projection, string partitionKey = null) + public virtual List ProjectMany(Expression> filter, Expression> projection, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable where TProjection : class @@ -848,7 +918,7 @@ namespace MongoDbGenericRepository /// The grouping criteria. /// The projected group result. /// The partition key of your document, if any. - public List GroupBy( + public virtual List GroupBy( Expression> groupingCriteria, Expression, TProjection>> groupProjection, string partitionKey = null) @@ -873,7 +943,7 @@ namespace MongoDbGenericRepository /// The grouping criteria. /// The projected group result. /// The partition key of your document, if any. - public List GroupBy(Expression> filter, + public virtual List GroupBy(Expression> filter, Expression> selector, Expression, TProjection>> projection, string partitionKey = null) @@ -898,7 +968,7 @@ namespace MongoDbGenericRepository /// 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) + public virtual 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(); @@ -913,7 +983,7 @@ namespace MongoDbGenericRepository /// 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) + public virtual async Task> GetPaginatedAsync(Expression> filter, int skipNumber = 0, int takeNumber = 50, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { @@ -930,7 +1000,7 @@ namespace MongoDbGenericRepository /// /// /// - public async Task GetAndUpdateOne(FilterDefinition filter, UpdateDefinition update, FindOneAndUpdateOptions options) where TDocument : IDocument + public virtual async Task GetAndUpdateOne(FilterDefinition filter, UpdateDefinition update, FindOneAndUpdateOptions options) where TDocument : IDocument { return await GetCollection().FindOneAndUpdateAsync(filter, update, options); } @@ -944,7 +1014,7 @@ namespace MongoDbGenericRepository /// /// /// - public async Task GetAndUpdateOne(FilterDefinition filter, UpdateDefinition update, FindOneAndUpdateOptions options) + public virtual async Task GetAndUpdateOne(FilterDefinition filter, UpdateDefinition update, FindOneAndUpdateOptions options) where TDocument : IDocument where TKey : IEquatable { diff --git a/MongoDbGenericRepository/MongoDbContext.cs b/MongoDbGenericRepository/MongoDbContext.cs index d0488a0..8771746 100644 --- a/MongoDbGenericRepository/MongoDbContext.cs +++ b/MongoDbGenericRepository/MongoDbContext.cs @@ -60,27 +60,29 @@ namespace MongoDbGenericRepository } /// - /// The private GetCollection method + /// Extracts the CollectionName attribute from the entity type, if any. /// /// The type representing a Document. - /// - public IMongoCollection GetCollection() + /// The name of the collection in which the TDocument is stored. + private string GetAttributeCollectionName() { - var collectionNameAttribute = typeof(TDocument).GetTypeInfo().GetCustomAttributes(typeof(CollectionNameAttribute)).FirstOrDefault() as CollectionNameAttribute; - var name = collectionNameAttribute?.Name ?? Pluralize(); - return Database.GetCollection(name); - } + return (typeof(TDocument).GetTypeInfo() + .GetCustomAttributes(typeof(CollectionNameAttribute)) + .FirstOrDefault() as CollectionNameAttribute)?.Name; + } /// /// Returns a collection for a document type that has a partition key. /// /// The type representing a Document. /// The value of the partition key. - public IMongoCollection GetCollection(string partitionKey) where TDocument : IDocument + public IMongoCollection GetCollection(string partitionKey = null) where TDocument : IDocument { - var collectionNameAttribute = typeof(TDocument).GetTypeInfo().GetCustomAttributes(typeof(CollectionNameAttribute)).FirstOrDefault() as CollectionNameAttribute; - var name = partitionKey + "-" + collectionNameAttribute?.Name ?? Pluralize(); - return Database.GetCollection(name); + if (string.IsNullOrEmpty(partitionKey)) + { + return Database.GetCollection(GetAttributeCollectionName() ?? Pluralize()); + } + return Database.GetCollection(partitionKey + "-" + GetAttributeCollectionName() ?? Pluralize()); } /// @@ -93,10 +95,12 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - var collectionNameAttribute = typeof(TDocument).GetTypeInfo().GetCustomAttributes(typeof(CollectionNameAttribute)).FirstOrDefault() as CollectionNameAttribute; - var name = partitionKey + "-" + collectionNameAttribute?.Name ?? Pluralize(); - return Database.GetCollection(name); - } + if (string.IsNullOrEmpty(partitionKey)) + { + return Database.GetCollection(GetAttributeCollectionName() ?? Pluralize()); + } + return Database.GetCollection(partitionKey + "-" + GetAttributeCollectionName() ?? Pluralize()); + } /// /// Drops a collection, use very carefully. @@ -104,9 +108,7 @@ namespace MongoDbGenericRepository /// The type representing a Document. public void DropCollection() { - var collectionNameAttribute = typeof(TDocument).GetTypeInfo().GetCustomAttributes(typeof(CollectionNameAttribute)).FirstOrDefault() as CollectionNameAttribute; - var name = collectionNameAttribute?.Name ?? Pluralize(); - Database.DropCollection(name); + Database.DropCollection(GetAttributeCollectionName() ?? Pluralize()); } /// @@ -115,9 +117,7 @@ namespace MongoDbGenericRepository /// The type representing a Document. public void DropCollection(string partitionKey) { - var collectionNameAttribute = typeof(TDocument).GetTypeInfo().GetCustomAttributes(typeof(CollectionNameAttribute)).FirstOrDefault() as CollectionNameAttribute; - var name = partitionKey + "-" + collectionNameAttribute?.Name ?? Pluralize(); - Database.DropCollection(name); + Database.DropCollection(partitionKey + "-" + GetAttributeCollectionName() ?? Pluralize()); } /// diff --git a/MongoDbGenericRepository/ReadOnlyMongoRepository.cs b/MongoDbGenericRepository/ReadOnlyMongoRepository.cs index 86ff2be..2a4e6f0 100644 --- a/MongoDbGenericRepository/ReadOnlyMongoRepository.cs +++ b/MongoDbGenericRepository/ReadOnlyMongoRepository.cs @@ -425,26 +425,13 @@ namespace MongoDbGenericRepository /// The type of the primary key. /// The collection partition key. /// - protected IMongoCollection GetCollection(string partitionKey) + protected IMongoCollection GetCollection(string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { return MongoDbContext.GetCollection(partitionKey); } - /// - /// Gets a collections for the type TDocument - /// - /// The document type. - /// The type of the primary key. - /// - protected IMongoCollection GetCollection() - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbContext.GetCollection(); - } - /// /// Gets a collections for a potentially partitioned document type. ///