Compare commits

...

111 Commits

Author SHA1 Message Date
Alexandre SPIESER 71b64c84a0 Merge pull request #39 from alexandre-spieser/alex/CancellationTokenWork
Alex/cancellation token work
2021-03-15 11:15:00 +00:00
Alexandre SPIESER 5f6e015bf2 fix mistake: missing cancellation token 2021-03-15 11:07:35 +00:00
Alexandre SPIESER 6d8e358ccc reference package in tests 2021-03-15 09:45:15 +00:00
Alexandre SPIESER 76a1aab671 pushed cancellation token changes 2021-03-15 08:03:50 +00:00
Alexandre SPIESER eebdc89575 adding cancellation token 2021-03-12 10:13:28 +00:00
Alexandre SPIESER ee4950c5d4 Merge branch 'master' into alex/UpdateMany 2021-03-10 08:45:10 +00:00
Alexandre SPIESER 658c753989 Added cancellation tokens (ongoing) 2021-03-10 08:44:50 +00:00
Alexandre SPIESER 0e8d629a8f Update README.md 2020-06-09 17:18:43 +01:00
Alexandre SPIESER ba3f876f95 Merge pull request #35 from alexandre-spieser/alex/UpdateMany
remove default option: IsUpset = true in update methods, to avoid une…
2020-06-09 09:02:31 +01:00
Alexandre SPIESER e4a36e5c60 remove default option: IsUpset = true in update methods, to avoid unexpected document insertions. 2020-06-09 09:01:53 +01:00
Alexandre SPIESER 592c30ed2c Merge pull request #34 from alexandre-spieser/alex/UpdateMany
Alex/update many
2020-06-06 12:16:58 +01:00
Alexandre SPIESER 83f1d2c7a6 nuget package works locally 2020-06-06 12:06:28 +01:00
Alexandre SPIESER ab294d1a5d remove ncrunch noise 2020-06-06 11:31:11 +01:00
Alexandre SPIESER dd8cbe3da7 Merge branch 'master' into alex/UpdateMany 2020-06-06 11:29:31 +01:00
Alexandre SPIESER 0844c51566 update many implementation, with tests 2020-06-06 11:28:46 +01:00
Alexandre SPIESER 601c0fd02d Update README.md 2020-06-06 08:31:35 +01:00
Alexandre SPIESER 91d15312e6 Update README.md 2020-06-05 07:26:28 +01:00
Alexandre SPIESER 54b2a63a8e Update README.md 2020-05-06 08:11:31 +01:00
Alexandre SPIESER dbb27aad39 Update README.md 2020-04-22 19:18:18 +01:00
Alexandre SPIESER afd0308849 Update README.md 2020-04-22 19:16:57 +01:00
Alexandre SPIESER 9cb35c5881 remove packaged dependencies 2020-02-05 21:37:44 +00:00
Alexandre SPIESER c5390214eb updated driver and test suite 2019-11-18 22:38:34 +00:00
Alexandre SPIESER ac1fd709a6 Merge pull request #26 from LeEmo86/upgrade-mongodbdriver
Updated the mongodb driver
2019-11-18 21:52:50 +00:00
Liam Flanagan f6b0aa274b Updated the mongodb driver 2019-11-18 19:20:57 +00:00
Alexandre SPIESER 7a82a281fb Merge pull request #23 from DanielGasson/master
Allow initialisation of MongoDbContext with connection string only
2019-06-18 21:50:50 +01:00
Daniel Gasson dca01b184c Allow initialisation of MongoDbContext with connection string only 2019-06-18 11:33:26 +01:00
Alexandre SPIESER b1cda2ac50 adding client session to mongodb updater methods 2019-05-18 19:49:44 +01:00
Alexandre SPIESER 8d6b796e7f Merge pull request #22 from alexandre-spieser/alex/refactorForKeyTypeRepo
1.4.0 release
2019-04-18 08:22:35 +01:00
Alexandre SPIESER 1a7763a312 1.4.0 release 2019-04-18 08:21:18 +01:00
Alexandre SPIESER 77cc85574c Update BaseMongoRepository.TKey.Update.cs 2019-04-17 19:08:13 +01:00
Alexandre SPIESER 846bb16730 Update BaseMongoRepository.TKey.Index.cs 2019-04-17 19:05:17 +01:00
Alexandre SPIESER 5e4cbfa1b3 Update BaseMongoRepository.TKey.Delete.cs 2019-04-17 19:04:38 +01:00
Alexandre SPIESER 804dc18c4f Update BaseMongoRepository.TKey.Create.cs 2019-04-17 19:03:59 +01:00
Alexandre SPIESER 182ee0a335 Update BaseMongoRepository.Update.cs 2019-04-17 19:02:57 +01:00
Alexandre SPIESER bd662d25d6 Update BaseMongoRepository.Index.cs 2019-04-17 19:00:33 +01:00
Alexandre SPIESER 6c8d4bdafb Update BaseMongoRepository.Delete.cs 2019-04-17 18:59:27 +01:00
Alexandre SPIESER 4d94a1b436 Update BaseMongoRepository.Create.cs 2019-04-17 18:58:47 +01:00
Alexandre SPIESER d91a644b4a Update README.md 2019-04-15 23:58:44 +01:00
Alexandre SPIESER 9d1950e9c7 Update README.md 2019-04-15 23:58:13 +01:00
Alexandre SPIESER 67d0a4c8a3 Update README.md 2019-04-15 00:48:19 +01:00
Alexandre SPIESER 1826668cea Update README.md 2019-04-15 00:47:06 +01:00
Alexandre SPIESER b855677efd Merge pull request #20 from alexandre-spieser/alex/refactorForKeyTypeRepo
added test suite for BaseMongoRepository<TKey>
2019-04-15 00:26:52 +01:00
Alexandre SPIESER 530309e9fc added test suite for BaseMongoRepository<TKey> 2019-04-15 00:26:10 +01:00
Alexandre SPIESER 69ad94e4a3 Merge pull request #19 from alexandre-spieser/alex/refactorForKeyTypeRepo
Alex/refactor for key type repo
2019-04-14 22:48:59 +01:00
Alexandre SPIESER baaf2b5ee9 tests now full clear the mongo collections / added GetSortedPaginatedAsync + tests 2019-04-14 22:47:06 +01:00
Alexandre SPIESER d2df667b3f added objectid tests 2019-04-14 20:18:37 +01:00
Alexandre SPIESER 8ccced66ea adding group by test 2019-04-14 20:07:56 +01:00
Alexandre SPIESER c92a126ecc Merge pull request #18 from alexandre-spieser/alex/refactorForKeyTypeRepo
Alex/refactor for key type repo
2019-04-14 19:36:44 +01:00
Alexandre SPIESER 2207f2f1a1 rename after full refactor 2019-04-14 19:31:28 +01:00
Alexandre SPIESER 0626292d09 fixed some tests 2019-04-14 18:10:45 +01:00
Alexandre SPIESER 29f01d2dab better segregation of concern and interfaces. 2019-04-14 17:58:31 +01:00
Alexandre SPIESER a7391e06f8 first step to split function into separate classes for better reuse and easier maintenance. 2019-04-11 23:59:34 +01:00
Alexandre SPIESER 43677b72a1 Merge pull request #16 from alexandre-spieser/alex/sum
Alex/sum
2019-04-10 23:59:11 +01:00
Alexandre SPIESER 2f29efafe3 SumByDecimal() test 2019-04-10 23:57:52 +01:00
Alexandre SPIESER d2f465b063 reorg + inheritance setup, using interface segregation to split concern / exposure of <TDocument,TKey> methods. 2019-04-10 23:48:44 +01:00
Alexandre SPIESER 75b894cb2a ran tests + removed obsolete methods 2019-04-10 22:07:15 +01:00
Alexandre SPIESER ba723be738 adding Key typed base repo functionality 2019-04-04 23:45:07 +01:00
Alexandre SPIESER f773e599d0 some good progress on refactoring into the KeyTyped repo for read only functionality 2019-04-04 22:48:09 +01:00
Alexandre SPIESER 17653b05f7 Update README.md
updated copyright year
2019-03-22 18:27:46 +00:00
Alexandre SPIESER 69903fd69b Merge branch 'master' into alex/sum 2019-02-10 17:00:23 +00:00
Alexandre SPIESER 9edd7e97fe moving TKEY related methods to there own partial class in the readonly repo 2019-02-07 08:48:36 +00:00
Alexandre SPIESER b77978e57a introucting KeyTypedReadOnlyMongoRepository 2019-02-07 08:47:27 +00:00
Alexandre SPIESER 648b57612d Merge pull request #14 from alexandre-spieser/alex/sum
Alex/sum
2019-02-04 23:13:28 +00:00
Alexandre SPIESER 4ac0ffe91c added tests for the sumbyasync methods 2019-02-04 23:11:36 +00:00
Alexandre SPIESER eaa90d67f5 sum for decimal fields, untested. 2019-01-02 23:43:37 +00:00
Alexandre SPIESER 2d866d966c Update MongoDbContext.cs
Added a MongoDbContext ctor that takes a MongoClient for custom setup.
2018-12-04 12:58:44 +00:00
Alexandre SPIESER ffc7e65b7b Update README.md 2018-10-07 19:46:34 +01:00
alexandre-spieser 0cf24b1dcf integration tested index management functionality 2018-10-07 19:05:59 +01:00
alexandre-spieser fd8f98e375 adding more tests 2018-10-01 22:31:08 +01:00
alexandre-spieser fa6687c084 fixed test by adding semaphores. Also reduced collections name to avoid hitting the 127 byte limit regarding index names. 2018-09-30 19:26:25 +01:00
alexandre-spieser 0b939592ba Implementation of index management.CreateTextIndexWithOptionAsync is failing. 2018-09-30 19:07:38 +01:00
alexandre-spieser ad18170804 work on indexes continued 2018-09-17 22:39:14 +01:00
alexandre-spieser 099e16a88c prep work on indexes methods 2018-09-17 08:41:36 +01:00
alexandre-spieser e41a73f745 1.3.7 release 2018-09-09 18:55:53 +01:00
alexandre-spieser 526adf0a23 remove unused using statements 2018-09-09 13:31:42 +01:00
alexandre-spieser db4061dc3c cleanup. Removing redundant GetCollection and Drop collection method, removed static constructor, added a virtual initialization method. 2018-09-09 13:05:45 +01:00
alexandre-spieser 72ea6e7999 clean up + full support for bulk insertion and deletion of documents of the same type but with different partitionkey values 2018-09-09 12:14:43 +01:00
alexandre-spieser 7f126a098d support insertion of documents with different PartitionKey values 2018-09-03 21:46:30 +01:00
alexandre-spieser 456af09a84 + Upgraded packages
+ Added GetByMax, GetByMaxAsync, GetByMin, GetByMinAsync, GetMaxValue and GetMaxValueAsync Methods (GetMinValue and GetMinValueAsync will come in another PR)
+ Added tests
2018-08-05 21:10:41 +01:00
Alexandre SPIESER f0af32adca Update copyright year to 2018 2018-05-11 22:53:43 +01:00
alexandre-spieser 345fca2e6e Added summary where needed. 2018-03-06 23:11:33 +00:00
alexandre-spieser 57d332ef2a Add support for ObjectId type for the Id of the document. 2018-03-05 23:07:56 +00:00
Alexandre SPIESER 2f6515a809 Merge pull request #3 from alexandre-spieser/add-license-1
Create LICENSE
2018-02-24 12:22:58 +00:00
Alexandre SPIESER 82dc2f2024 Create LICENSE 2018-02-24 12:22:49 +00:00
Alexandre SPIESER bc992e8c61 Update README.md 2018-02-16 15:11:09 +00:00
Alexandre SPIESER 47e85f1760 Update README.md 2018-02-16 15:10:18 +00:00
alexandre-spieser 6f5eb71dad Prepare for 1.3.5 release. 2018-02-10 18:32:45 +00:00
alexandre-spieser ed0d206a97 Merge branch 'master' of https://github.com/alexandre-spieser/mongodb-generic-repository 2018-02-10 18:17:42 +00:00
alexandre-spieser 40ff874cf6 CoreIntegrationTests refactored and passing. 2018-02-10 18:16:14 +00:00
alexandre-spieser 9fc74fc28e cleanup redundant tests. 2018-02-10 16:46:59 +00:00
alexandre-spieser 5270271008 Continues refactoring tests, added overload for UpdateOne and UpdateOneAsync so that we can pass a LINQ query to the method. 2018-02-10 16:38:47 +00:00
alexandre-spieser bf2119432e Test refactoring, continued. 2018-02-10 14:13:10 +00:00
Alexandre SPIESER e581586161 Update README.md 2018-02-07 12:59:13 +00:00
alexandre-spieser 1a83abd25f refactoring test classes. 2018-02-05 23:48:11 +00:00
Alexandre SPIESER 03b0e4265b Merge pull request #2 from Etchelon/master
Add CollectionName attribute for allowing explicit naming of collections
2018-02-05 20:32:50 +00:00
Andrea Bertoldo c117bf2a7f Add CollectionName attribute for allowing explicit naming of collections 2018-02-05 14:48:26 +01:00
Alexandre SPIESER c50e4d086e Update README.md 2018-01-27 16:44:03 +00:00
alexandre-spieser 3a42a1c574 Upgraded mongodb driver + new package version released. 2018-01-27 15:58:16 +00:00
alexandre-spieser 67e7318021 updating mongodb driver to version 2.5.0 for MongoDB 3.6 support. 2018-01-27 14:49:13 +00:00
alexandre-spieser 29012d1e52 nuget package update 2018-01-27 14:41:39 +00:00
alexandre-spieser e15c1e4ad2 Refactoring to have a greater separation of concern. 2017-12-06 23:20:53 +00:00
alexandre-spieser 3d104764ae added dependencies 2017-11-19 19:05:22 +00:00
alexandre-spieser 3af68c06db Merge branch 'master' of https://github.com/alexandre-spieser/mongodb-generic-repository 2017-11-17 18:39:38 +00:00
alexandre-spieser a3ae98d077 added comments and updated nuspec 2017-11-17 18:39:34 +00:00
Alexandre SPIESER aff276f9e3 Update README.md 2017-11-16 17:14:40 +00:00
Alexandre SPIESER e91c89f054 Update README.md 2017-11-01 08:27:59 +00:00
alexandre-spieser 657beeac99 The MongoDbRepository now has a constructor that takes an IMongoDatabase. 2017-11-01 08:18:29 +00:00
alexandre-spieser fbb07475a1 Added tests for IdentityUsers 2017-10-29 19:29:43 +00:00
Alexandre SPIESER 30ea910b9c Update README.md 2017-10-22 01:06:26 +01:00
Alexandre SPIESER aae71cddc3 Update README.md 2017-10-02 00:20:50 +01:00
Alexandre SPIESER ad2cd66a7d Update README.md 2017-10-01 22:47:37 +01:00
126 changed files with 23132 additions and 14834 deletions
+22
View File
@@ -0,0 +1,22 @@
using CoreIntegrationTests.Infrastructure;
using MongoDB.Bson;
namespace CoreIntegrationTests
{
public class CoreObjectIdTestDocument : TestDoc<ObjectId>
{
}
public class CRUDObjectIdTests : MongoDbTKeyDocumentTestBase<CoreObjectIdTestDocument, ObjectId>
{
public CRUDObjectIdTests(MongoDbTestFixture<CoreObjectIdTestDocument, ObjectId> fixture) : base(fixture)
{
}
public override string GetClassName()
{
return "CRUDObjectIdTests";
}
}
}
@@ -0,0 +1,31 @@
using CoreIntegrationTests.Infrastructure;
using MongoDbGenericRepository.Attributes;
using MongoDbGenericRepository.Models;
using System;
namespace CoreIntegrationTests
{
[CollectionName("CoreTestingCNameAttrPart")]
public class CorePartitionedCollectionNameDoc : TestDoc, IPartitionedDocument
{
public CorePartitionedCollectionNameDoc()
{
PartitionKey = "CoreTestPartitionKeyCollectionName";
}
public string PartitionKey { get; set; }
}
public class CRUDPartitionedCollectionNameAttributeTests : MongoDbDocumentTestBase<CorePartitionedCollectionNameDoc>
{
public CRUDPartitionedCollectionNameAttributeTests(MongoDbTestFixture<CorePartitionedCollectionNameDoc, Guid> fixture) : base(fixture)
{
}
public override string GetClassName()
{
return "CoreCRUDPartitionedCollectionNameAttributeTests";
}
}
}
@@ -0,0 +1,28 @@
using CoreIntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using System;
namespace CoreIntegrationTests
{
public class CorePartitionedDoc : TestDoc, IPartitionedDocument
{
public CorePartitionedDoc()
{
PartitionKey = "CoreTestPartitionKey";
}
public string PartitionKey { get; set; }
}
public class CRUDPartitionedTests : MongoDbDocumentTestBase<CorePartitionedDoc>
{
public CRUDPartitionedTests(MongoDbTestFixture<CorePartitionedDoc, Guid> fixture) : base(fixture)
{
}
public override string GetClassName()
{
return "CoreCRUDPartitionedTests";
}
}
}
@@ -0,0 +1,65 @@
using CoreIntegrationTests.Infrastructure;
using MongoDB.Bson;
using MongoDbGenericRepository.Attributes;
using MongoDbGenericRepository.Models;
using System;
namespace CoreIntegrationTests
{
#region Guid Type
[CollectionName("TestingCNameAttrPartTKey")]
public class CoreTKeyPartitionedCollectionNameDoc : TestDoc<Guid>, IPartitionedDocument
{
public CoreTKeyPartitionedCollectionNameDoc()
{
PartitionKey = "CoreTestPartitionKey";
}
public string PartitionKey { get; set; }
}
public class CRUDTKeyPartitionedCollectionNameAttributeTests : MongoDbTKeyDocumentTestBase<CoreTKeyPartitionedCollectionNameDoc, Guid>
{
public CRUDTKeyPartitionedCollectionNameAttributeTests(MongoDbTestFixture<CoreTKeyPartitionedCollectionNameDoc, Guid> fixture) : base(fixture)
{
}
public override string GetClassName()
{
return "CoreCRUDTKeyPartitionedCollectionNameAttributeTests";
}
}
#endregion Guid Type
#region ObjectId Type
[CollectionName("TestingCNameAttrPartObjectId")]
public class CoreObjectIdPartitionedCollectionNameDoc : TestDoc<ObjectId>, IPartitionedDocument
{
public CoreObjectIdPartitionedCollectionNameDoc()
{
PartitionKey = "CoreTestPartitionKeyObjectId";
}
public string PartitionKey { get; set; }
}
public class CRUDObjectIdPartitionedCollectionNameAttributeTests : MongoDbTKeyDocumentTestBase<CoreObjectIdPartitionedCollectionNameDoc, ObjectId>
{
public CRUDObjectIdPartitionedCollectionNameAttributeTests(MongoDbTestFixture<CoreObjectIdPartitionedCollectionNameDoc, ObjectId> fixture) : base(fixture)
{
}
public override string GetClassName()
{
return "CoreCRUDTKeyPartitionedCollectionNameAttributeTests";
}
}
#endregion ObjectId Type
}
@@ -0,0 +1,28 @@
using CoreIntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using System;
namespace CoreIntegrationTests
{
public class CorePartitionedTKeyTestDocument : TestDoc<Guid>, IPartitionedDocument
{
public CorePartitionedTKeyTestDocument()
{
PartitionKey = "CoreTestPartitionKey";
}
public string PartitionKey { get; set; }
}
public class CRUDTKeyPartitionedTests : MongoDbTKeyDocumentTestBase<CorePartitionedTKeyTestDocument, Guid>
{
public CRUDTKeyPartitionedTests(MongoDbTestFixture<CorePartitionedTKeyTestDocument, Guid> fixture) : base(fixture)
{
}
public override string GetClassName()
{
return "CoreCRUDTKeyPartitionedTests";
}
}
}
+22
View File
@@ -0,0 +1,22 @@
using CoreIntegrationTests.Infrastructure;
using System;
namespace CoreIntegrationTests
{
public class CoreTKeyTestDocument : TestDoc<Guid>
{
}
public class CRUDTKeyTests : MongoDbTKeyDocumentTestBase<CoreTKeyTestDocument, Guid>
{
public CRUDTKeyTests(MongoDbTestFixture<CoreTKeyTestDocument, Guid> fixture) : base(fixture)
{
}
public override string GetClassName()
{
return "CreateTKeyTests";
}
}
}
+21
View File
@@ -0,0 +1,21 @@
using CoreIntegrationTests.Infrastructure;
using System;
namespace CoreIntegrationTests
{
public class CoreTestDocument : TestDoc
{
}
public class CRUDTests : MongoDbDocumentTestBase<CoreTestDocument>
{
public CRUDTests(MongoDbTestFixture<CoreTestDocument, Guid> fixture) : base(fixture)
{
}
public override string GetClassName()
{
return "CRUDTests";
}
}
}
@@ -1,20 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework> <TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20170810-02" /> <PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.1.2" />
<PackageReference Include="MongoDB.Driver" Version="2.4.4" /> <PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="2.1.2" />
<PackageReference Include="xunit" Version="2.3.0-beta5-build3769" /> <PackageReference Include="MongoDB.Driver" Version="2.12.0" />
<PackageReference Include="xunit.runner.console" Version="2.3.0-beta5-build3769" /> <PackageReference Include="MongoDbGenericRepository" Version="1.4.6" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta5-build3769" /> <PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.console" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0-beta4-build3742" /> <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0-beta4-build3742" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\MongoDbGenericRepository\MongoDbGenericRepository.csproj" /> <Reference Include="System.Configuration">
<HintPath>..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Configuration.dll</HintPath>
</Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -1,67 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using Xunit;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class CreateTestsPartitionedDocument : PartitionedDocument
{
public CreateTestsPartitionedDocument() : base("TestPartitionKey")
{
Version = 1;
}
public string SomeContent { get; set; }
}
public class CreatePartitionedTests : BaseMongoDbRepositoryTests<CreateTestsPartitionedDocument>
{
private void PartitionedAddOne()
{
// Arrange
var document = new CreateTestsPartitionedDocument();
// Act
SUT.AddOne(document);
// Assert
long count = SUT.Count<CreateTestsPartitionedDocument>(e => e.Id == document.Id, PartitionKey);
Xunit.Assert.Equal(1, count);
}
[Fact]
public async Task PartitionedAddOneAsync()
{
// Arrange
var document = new CreateTestsPartitionedDocument();
// Act
await SUT.AddOneAsync(document);
// Assert
long count = SUT.Count<CreateTestsPartitionedDocument>(e => e.Id == document.Id, PartitionKey);
Assert.Equal(1, count);
}
[Fact]
public void PartitionedAddMany()
{
// Arrange
var documents = new List<CreateTestsPartitionedDocument> { new CreateTestsPartitionedDocument(), new CreateTestsPartitionedDocument() };
// Act
SUT.AddMany(documents);
// Assert
long count = SUT.Count<CreateTestsPartitionedDocument>(e => e.Id == documents[0].Id || e.Id == documents[1].Id, PartitionKey);
Assert.Equal(2, count);
}
[Fact]
public async Task PartitionedAddManyAsync()
{
// Arrange
var documents = new List<CreateTestsPartitionedDocument> { new CreateTestsPartitionedDocument(), new CreateTestsPartitionedDocument() };
// Act
await SUT.AddManyAsync(documents);
// Assert
long count = SUT.Count<CreateTestsPartitionedDocument>(e => e.Id == documents[0].Id || e.Id == documents[1].Id, PartitionKey);
Assert.Equal(2, count);
}
}
}
-68
View File
@@ -1,68 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using Xunit;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class CreateTestsDocument : Document
{
public CreateTestsDocument()
{
Version = 2;
}
public string SomeContent { get; set; }
}
public class CreateTests : BaseMongoDbRepositoryTests<CreateTestsDocument>
{
[Fact]
public void AddOne()
{
// Arrange
var document = new CreateTestsDocument();
// Act
SUT.AddOne(document);
// Assert
long count = SUT.Count<CreateTestsDocument>(e => e.Id == document.Id);
Assert.Equal(1, count);
}
[Fact]
public async Task AddOneAsync()
{
// Arrange
var document = new CreateTestsDocument();
// Act
await SUT.AddOneAsync(document);
// Assert
long count = SUT.Count<CreateTestsDocument>(e => e.Id == document.Id);
Assert.Equal(1, count);
}
[Fact]
public void AddMany()
{
// Arrange
var documents = new List<CreateTestsDocument> { new CreateTestsDocument(), new CreateTestsDocument() };
// Act
SUT.AddMany(documents);
// Assert
long count = SUT.Count<CreateTestsDocument>(e => e.Id == documents[0].Id || e.Id == documents[1].Id);
Assert.Equal(2, count);
}
[Fact]
public async Task AddManyAsync()
{
// Arrange
var documents = new List<CreateTestsDocument> { new CreateTestsDocument(), new CreateTestsDocument() };
// Act
await SUT.AddManyAsync(documents);
// Assert
long count = SUT.Count<CreateTestsDocument>(e => e.Id == documents[0].Id || e.Id == documents[1].Id);
Assert.Equal(2, count);
}
}
}
@@ -1,129 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using Xunit;
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<DeleteTestsPartitionedDocument>
{
[Fact]
public void PartitionedDeleteOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.DeleteOne(document);
// Assert
Assert.Equal(1, result);
Assert.False(SUT.Any<DeleteTestsPartitionedDocument>(e => e.Id == document.Id, PartitionKey));
}
[Fact]
public void PartitionedDeleteOneLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.DeleteOne<DeleteTestsPartitionedDocument>(e => e.Id == document.Id, PartitionKey);
// Assert
Assert.Equal(1, result);
Assert.False(SUT.Any<DeleteTestsPartitionedDocument>(e => e.Id == document.Id, PartitionKey));
}
[Fact]
public async Task PartitionedDeleteOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.DeleteOneAsync(document);
// Assert
Assert.Equal(1, result);
Assert.False(SUT.Any<DeleteTestsPartitionedDocument>(e => e.Id == document.Id, PartitionKey));
}
[Fact]
public async Task PartitionedDeleteOneAsyncLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.DeleteOneAsync<DeleteTestsPartitionedDocument>(e => e.Id == document.Id, PartitionKey);
// Assert
Assert.Equal(1, result);
Assert.False(SUT.Any<DeleteTestsPartitionedDocument>(e => e.Id == document.Id, PartitionKey));
}
[Fact]
public async Task PartitionedDeleteManyAsyncLinq()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "DeleteManyAsyncLinqContent");
SUT.AddMany(documents);
// Act
var result = await SUT.DeleteManyAsync<DeleteTestsPartitionedDocument>(e => e.SomeContent == "DeleteManyAsyncLinqContent", PartitionKey);
// Assert
Assert.Equal(5, result);
Assert.False(SUT.Any<DeleteTestsPartitionedDocument>(e => e.SomeContent == "DeleteManyAsyncLinqContent", PartitionKey));
}
[Fact]
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.Equal(5, result);
Assert.False(SUT.Any<DeleteTestsPartitionedDocument>(e => e.SomeContent == "DeleteManyAsyncLinqContent", PartitionKey));
}
[Fact]
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<DeleteTestsPartitionedDocument>(e => e.SomeContent == content, PartitionKey);
// Assert
Assert.Equal(5, result);
Assert.False(SUT.Any<DeleteTestsPartitionedDocument>(e => e.SomeContent == content, PartitionKey));
}
[Fact]
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.Equal(5, result);
Assert.False(SUT.Any<DeleteTestsPartitionedDocument>(e => e.SomeContent == content, PartitionKey));
}
}
}
-129
View File
@@ -1,129 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using Xunit;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class DeleteTestsDocument : Document
{
public DeleteTestsDocument()
{
Version = 2;
}
public string SomeContent { get; set; }
}
public class DeleteTests : BaseMongoDbRepositoryTests<DeleteTestsDocument>
{
[Fact]
public void DeleteOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.DeleteOne(document);
// Assert
Assert.Equal(1, result);
Assert.False(SUT.Any<DeleteTestsDocument>(e => e.Id == document.Id));
}
[Fact]
public void DeleteOneLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.DeleteOne<DeleteTestsDocument>(e => e.Id == document.Id);
// Assert
Assert.Equal(1, result);
Assert.False(SUT.Any<DeleteTestsDocument>(e => e.Id == document.Id));
}
[Fact]
public async Task DeleteOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.DeleteOneAsync(document);
// Assert
Assert.Equal(1, result);
Assert.False(SUT.Any<DeleteTestsDocument>(e => e.Id == document.Id));
}
[Fact]
public async Task DeleteOneAsyncLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.DeleteOneAsync<DeleteTestsDocument>(e => e.Id == document.Id);
// Assert
Assert.Equal(1, result);
Assert.False(SUT.Any<DeleteTestsDocument>(e => e.Id == document.Id));
}
[Fact]
public async Task DeleteManyAsyncLinq()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "DeleteManyAsyncLinqContent");
SUT.AddMany(documents);
// Act
var result = await SUT.DeleteManyAsync<DeleteTestsDocument>(e => e.SomeContent == "DeleteManyAsyncLinqContent");
// Assert
Assert.Equal(5, result);
Assert.False(SUT.Any<DeleteTestsDocument>(e => e.SomeContent == "DeleteManyAsyncLinqContent"));
}
[Fact]
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.Equal(5, result);
Assert.False(SUT.Any<DeleteTestsDocument>(e => e.SomeContent == "DeleteManyAsyncLinqContent"));
}
[Fact]
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<DeleteTestsDocument>(e => e.SomeContent == content);
// Assert
Assert.Equal(5, result);
Assert.False(SUT.Any<DeleteTestsDocument>(e => e.SomeContent == content));
}
[Fact]
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.Equal(5, result);
Assert.False(SUT.Any<DeleteTestsDocument>(e => e.SomeContent == content));
}
}
}
+77
View File
@@ -0,0 +1,77 @@
using CoreIntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Generic;
using Xunit;
using Microsoft.AspNetCore.Identity;
using System.Threading.Tasks;
namespace CoreIntegrationTests
{
public class MongoIdentityUser<TKey> : IdentityUser<TKey>, IDocument<TKey>
where TKey : IEquatable<TKey>
{
public int Version { get; set; }
}
public class IdentityUserTest : MongoIdentityUser<Guid>, IDocument<Guid>
{
public IdentityUserTest()
{
Id = Guid.NewGuid();
Version = 2;
}
public string SomeContent { get; set; }
}
public class IdentityUserTests : BaseMongoDbRepositoryTests<IdentityUserTest>
{
[Fact]
public void AddOne()
{
// Arrange
var document = new IdentityUserTest();
// Act
SUT.AddOne<IdentityUserTest, Guid>(document);
// Assert
long count = SUT.Count<IdentityUserTest, Guid>(e => e.Id == document.Id);
Assert.Equal(1, count);
}
[Fact]
public async Task AddOneAsync()
{
// Arrange
var document = new IdentityUserTest();
// Act
await SUT.AddOneAsync<IdentityUserTest, Guid>(document);
// Assert
long count = SUT.Count<IdentityUserTest, Guid>(e => e.Id == document.Id);
Assert.Equal(1, count);
}
[Fact]
public void AddMany()
{
// Arrange
var documents = new List<IdentityUserTest> { new IdentityUserTest(), new IdentityUserTest() };
// Act
SUT.AddMany<IdentityUserTest, Guid>(documents);
// Assert
long count = SUT.Count<IdentityUserTest, Guid>(e => e.Id == documents[0].Id || e.Id == documents[1].Id);
Assert.Equal(2, count);
}
[Fact]
public async Task AddManyAsync()
{
// Arrange
var documents = new List<IdentityUserTest> { new IdentityUserTest(), new IdentityUserTest() };
// Act
await SUT.AddManyAsync<IdentityUserTest, Guid>(documents);
// Assert
long count = SUT.Count<IdentityUserTest, Guid>(e => e.Id == documents[0].Id || e.Id == documents[1].Id);
Assert.Equal(2, count);
}
}
}
@@ -2,10 +2,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using System; using System;
namespace IntegrationTests.Infrastructure namespace CoreIntegrationTests.Infrastructure
{ {
public class BaseMongoDbRepositoryTests<T> : IDisposable where T : Document, new() public class BaseMongoDbRepositoryTests<T> : IDisposable where T : new()
{ {
public T CreateTestDocument() public T CreateTestDocument()
{ {
@@ -44,6 +44,7 @@ namespace IntegrationTests.Infrastructure
public void Init() public void Init()
{ {
MongoDbConfig.EnsureConfigured();
SUT = TestRepository.Instance; SUT = TestRepository.Instance;
} }
@@ -0,0 +1,15 @@
using System;
namespace CoreIntegrationTests.Infrastructure
{
/// <summary>
/// A class holding global variables.
/// </summary>
public static class GlobalVariables
{
/// <summary>
/// A random number generator.
/// </summary>
public static Random Random = new Random();
}
}
@@ -1,6 +1,6 @@
using MongoDbGenericRepository; using MongoDbGenericRepository;
namespace IntegrationTests namespace CoreIntegrationTests
{ {
public interface ITestRepository : IBaseMongoRepository public interface ITestRepository : IBaseMongoRepository
{ {
@@ -0,0 +1,41 @@
using MongoDB.Bson.Serialization.Conventions;
using System.Threading;
namespace CoreIntegrationTests.Infrastructure
{
internal static class MongoDbConfig
{
private static bool _initialized = false;
private static object _initializationLock = new object();
private static object _initializationTarget;
public static void EnsureConfigured()
{
EnsureConfiguredImpl();
}
private static void EnsureConfiguredImpl()
{
LazyInitializer.EnsureInitialized(ref _initializationTarget, ref _initialized, ref _initializationLock, () =>
{
Configure();
return null;
});
}
private static void Configure()
{
RegisterConventions();
}
private static void RegisterConventions()
{
var pack = new ConventionPack
{
new IgnoreIfNullConvention(false),
new CamelCaseElementNameConvention(),
};
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,381 @@
using MongoDB.Driver;
using MongoDbGenericRepository;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace CoreIntegrationTests.Infrastructure
{
public abstract partial class MongoDbDocumentTestBase<T> :
IClassFixture<MongoDbTestFixture<T, Guid>>
where T : TestDoc, new()
{
#region Update One
[Fact]
public void UpdateOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
var content = GetContent();
document.SomeContent = content;
// Act
var result = SUT.UpdateOne<T>(document);
// Assert
Assert.True(result);
var updatedDocument = SUT.GetById<T>(document.Id, PartitionKey);
Assert.True(null != updatedDocument, GetTestName());
Assert.True(content == updatedDocument.SomeContent, GetTestName());
}
[Fact]
public async Task UpdateOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
var content = GetContent();
document.SomeContent = content;
// Act
var result = await SUT.UpdateOneAsync<T>(document);
// Assert
Assert.True(result);
var updatedDocument = SUT.GetById<T>(document.Id, PartitionKey);
Assert.True(null != updatedDocument, GetTestName());
Assert.True(content == updatedDocument.SomeContent, GetTestName());
}
[Fact]
public void UpdateOneField()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
var content = GetContent();
// Act
var result = SUT.UpdateOne<T, string>(document, x => x.SomeContent, content);
// Assert
Assert.True(result, GetTestName());
var updatedDocument = SUT.GetById<T>(document.Id, PartitionKey);
Assert.True(null != updatedDocument, GetTestName());
Assert.True(content == updatedDocument.SomeContent, GetTestName());
}
[Fact]
public async Task UpdateOneFieldAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
var content = GetContent();
// Act
var result = await SUT.UpdateOneAsync<T, string>(document, x => x.SomeContent, content);
// Assert
Assert.True(result, GetTestName());
var updatedDocument = SUT.GetById<T>(document.Id, PartitionKey);
Assert.True(null != updatedDocument, GetTestName());
Assert.True(content == updatedDocument.SomeContent, GetTestName());
}
[Fact]
public void UpdateOneFieldWithFilter()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
var content = GetContent();
// Act
var result = SUT.UpdateOne<T, string>(x => x.Id.Equals(document.Id), x => x.SomeContent, content, PartitionKey);
// Assert
Assert.True(result, GetTestName());
var updatedDocument = SUT.GetById<T>(document.Id, PartitionKey);
Assert.True(null != updatedDocument, GetTestName());
Assert.True(content == updatedDocument.SomeContent, GetTestName());
}
[Fact]
public async Task UpdateOneFieldWithFilterAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
var content = GetContent();
// Act
var result = await SUT.UpdateOneAsync<T, string>(x => x.Id.Equals(document.Id), x => x.SomeContent, content, PartitionKey);
// Assert
Assert.True(result, GetTestName());
var updatedDocument = SUT.GetById<T>(document.Id, PartitionKey);
Assert.True(null != updatedDocument, GetTestName());
Assert.True(content == updatedDocument.SomeContent, GetTestName());
}
[Fact]
public async Task UpdateOneAsyncWithUpdateDefinition()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = MongoDB.Driver.Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = await SUT.UpdateOneAsync<T>(document, updateDef);
// Assert
Assert.True(result);
var updatedDocument = SUT.GetById<T>(document.Id, PartitionKey);
Assert.True(null != updatedDocument);
Assert.True(childrenToAdd[0].Type == updatedDocument.Children[0].Type, GetTestName());
Assert.True(childrenToAdd[0].Value == updatedDocument.Children[0].Value, GetTestName());
Assert.True(childrenToAdd[1].Type == updatedDocument.Children[1].Type, GetTestName());
Assert.True(childrenToAdd[1].Value == updatedDocument.Children[1].Value, GetTestName());
}
[Fact]
public void UpdateOneWithUpdateDefinition()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = MongoDB.Driver.Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = SUT.UpdateOne<T>(document, updateDef);
// Assert
Assert.True(result);
var updatedDocument = SUT.GetById<T>(document.Id, PartitionKey);
Assert.True(null != updatedDocument);
Assert.True(childrenToAdd[0].Type == updatedDocument.Children[0].Type, GetTestName());
Assert.True(childrenToAdd[0].Value == updatedDocument.Children[0].Value, GetTestName());
Assert.True(childrenToAdd[1].Type == updatedDocument.Children[1].Type, GetTestName());
Assert.True(childrenToAdd[1].Value == updatedDocument.Children[1].Value, GetTestName());
}
#endregion Update One
#region Update Many
[Fact]
public async Task UpdateManyWithLinqFilterAsync()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T>(documents);
var docIds = documents.Select(u => u.Id).ToArray();
var content = GetContent();
// Act
var result = await SUT.UpdateManyAsync<T, string>(x => docIds.Contains(x.Id), x => x.SomeContent, content, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocument = SUT.GetAll<T>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocument.Count == 2);
Assert.True(updatedDocument.All(u => u.SomeContent == content), GetTestName());
}
[Fact]
public async Task UpdateManyWithFilterDefinitionAsync()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T>(documents);
var docIds = documents.Select(u => u.Id).ToArray();
var filterDefinition = Builders<T>.Filter.Where(x => docIds.Contains(x.Id));
var content = GetContent();
// Act
var result = await SUT.UpdateManyAsync<T, string>(filterDefinition, x => x.SomeContent, content, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocument = SUT.GetAll<T>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocument.Count == 2);
Assert.True(updatedDocument.All(u => u.SomeContent == content), GetTestName());
}
[Fact]
public async Task UpdateManyWithLinqFilterAndUpdateDefinitionAsync()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T>(documents);
var docIds = documents.Select(u => u.Id).ToArray();
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
var content = GetContent();
// Act
var result = await SUT.UpdateManyAsync<T>(x => docIds.Contains(x.Id), updateDef, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocuments = SUT.GetAll<T>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocuments.Count == 2);
updatedDocuments.ForEach(updatedDocument =>
{
Assert.True(childrenToAdd[0].Type == updatedDocument.Children[0].Type, GetTestName());
Assert.True(childrenToAdd[0].Value == updatedDocument.Children[0].Value, GetTestName());
Assert.True(childrenToAdd[1].Type == updatedDocument.Children[1].Type, GetTestName());
Assert.True(childrenToAdd[1].Value == updatedDocument.Children[1].Value, GetTestName());
});
}
[Fact]
public async Task UpdateManyWithFilterAndUpdateDefinitionsAsync()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T>(documents);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
var docIds = documents.Select(u => u.Id).ToArray();
var filterDefinition = Builders<T>.Filter.Where(x => docIds.Contains(x.Id));
var content = GetContent();
// Act
var result = await SUT.UpdateManyAsync<T>(filterDefinition, updateDef, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocuments = SUT.GetAll<T>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocuments.Count == 2);
updatedDocuments.ForEach(updatedDocument =>
{
Assert.True(childrenToAdd[0].Type == updatedDocument.Children[0].Type, GetTestName());
Assert.True(childrenToAdd[0].Value == updatedDocument.Children[0].Value, GetTestName());
Assert.True(childrenToAdd[1].Type == updatedDocument.Children[1].Type, GetTestName());
Assert.True(childrenToAdd[1].Value == updatedDocument.Children[1].Value, GetTestName());
});
}
[Fact]
public void UpdateManyWithLinqFilter()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T>(documents);
var docIds = documents.Select(u => u.Id).ToArray();
var content = GetContent();
// Act
var result = SUT.UpdateMany<T, string>(x => docIds.Contains(x.Id), x => x.SomeContent, content, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocument = SUT.GetAll<T>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocument.Count == 2);
Assert.True(updatedDocument.All(u => u.SomeContent == content), GetTestName());
}
[Fact]
public void UpdateManyWithFilterDefinition()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T>(documents);
var docIds = documents.Select(u => u.Id).ToArray();
var filterDefinition = Builders<T>.Filter.Where(x => docIds.Contains(x.Id));
var content = GetContent();
// Act
var result = SUT.UpdateMany<T, string>(filterDefinition, x => x.SomeContent, content, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocument = SUT.GetAll<T>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocument.Count == 2);
Assert.True(updatedDocument.All(u => u.SomeContent == content), GetTestName());
}
[Fact]
public void UpdateManyWithLinqFilterAndUpdateDefinition()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T>(documents);
var docIds = documents.Select(u => u.Id).ToArray();
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
var content = GetContent();
// Act
var result = SUT.UpdateMany<T>(x => docIds.Contains(x.Id), updateDef, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocuments = SUT.GetAll<T>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocuments.Count == 2);
updatedDocuments.ForEach(updatedDocument =>
{
Assert.True(childrenToAdd[0].Type == updatedDocument.Children[0].Type, GetTestName());
Assert.True(childrenToAdd[0].Value == updatedDocument.Children[0].Value, GetTestName());
Assert.True(childrenToAdd[1].Type == updatedDocument.Children[1].Type, GetTestName());
Assert.True(childrenToAdd[1].Value == updatedDocument.Children[1].Value, GetTestName());
});
}
[Fact]
public void UpdateManyWithFilterAndUpdateDefinitions()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T>(documents);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
var docIds = documents.Select(u => u.Id).ToArray();
var filterDefinition = Builders<T>.Filter.Where(x => docIds.Contains(x.Id));
var content = GetContent();
// Act
var result = SUT.UpdateMany<T>(filterDefinition, updateDef, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocuments = SUT.GetAll<T>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocuments.Count == 2);
updatedDocuments.ForEach(updatedDocument =>
{
Assert.True(childrenToAdd[0].Type == updatedDocument.Children[0].Type, GetTestName());
Assert.True(childrenToAdd[0].Value == updatedDocument.Children[0].Value, GetTestName());
Assert.True(childrenToAdd[1].Type == updatedDocument.Children[1].Type, GetTestName());
Assert.True(childrenToAdd[1].Value == updatedDocument.Children[1].Value, GetTestName());
});
}
#endregion Update Many
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,377 @@
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace CoreIntegrationTests.Infrastructure
{
public abstract partial class MongoDbTKeyDocumentTestBase<T, TKey> :
IClassFixture<MongoDbTestFixture<T, TKey>>
where T : TestDoc<TKey>, new()
where TKey : IEquatable<TKey>
{
#region Update One
[Fact]
public void UpdateOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
var content = GetContent();
document.SomeContent = content;
// Act
var result = SUT.UpdateOne<T, TKey>(document);
// Assert
Assert.True(result);
var updatedDocument = SUT.GetById<T, TKey>(document.Id, PartitionKey);
Assert.True(null != updatedDocument, GetTestName());
Assert.True(content == updatedDocument.SomeContent, GetTestName());
}
[Fact]
public async Task UpdateOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
var content = GetContent();
document.SomeContent = content;
// Act
var result = await SUT.UpdateOneAsync<T, TKey>(document);
// Assert
Assert.True(result);
var updatedDocument = SUT.GetById<T, TKey>(document.Id, PartitionKey);
Assert.True(null != updatedDocument, GetTestName());
Assert.True(content == updatedDocument.SomeContent, GetTestName());
}
[Fact]
public void UpdateOneField()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
var content = GetContent();
// Act
var result = SUT.UpdateOne<T, TKey, string>(document, x => x.SomeContent, content);
// Assert
Assert.True(result, GetTestName());
var updatedDocument = SUT.GetById<T, TKey>(document.Id, PartitionKey);
Assert.True(null != updatedDocument, GetTestName());
Assert.True(content == updatedDocument.SomeContent, GetTestName());
}
[Fact]
public async Task UpdateOneFieldAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
var content = GetContent();
// Act
var result = await SUT.UpdateOneAsync<T, TKey, string>(document, x => x.SomeContent, content);
// Assert
Assert.True(result, GetTestName());
var updatedDocument = SUT.GetById<T, TKey>(document.Id, PartitionKey);
Assert.True(null != updatedDocument, GetTestName());
Assert.True(content == updatedDocument.SomeContent, GetTestName());
}
[Fact]
public void UpdateOneFieldWithFilter()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
var content = GetContent();
// Act
var result = SUT.UpdateOne<T, TKey, string>(x => x.Id.Equals(document.Id), x => x.SomeContent, content, PartitionKey);
// Assert
Assert.True(result, GetTestName());
var updatedDocument = SUT.GetById<T, TKey>(document.Id, PartitionKey);
Assert.True(null != updatedDocument, GetTestName());
Assert.True(content == updatedDocument.SomeContent, GetTestName());
}
[Fact]
public async Task UpdateOneFieldWithFilterAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
var content = GetContent();
// Act
var result = await SUT.UpdateOneAsync<T, TKey, string>(x => x.Id.Equals(document.Id), x => x.SomeContent, content, PartitionKey);
// Assert
Assert.True(result, GetTestName());
var updatedDocument = SUT.GetById<T, TKey>(document.Id, PartitionKey);
Assert.True(null != updatedDocument, GetTestName());
Assert.True(content == updatedDocument.SomeContent, GetTestName());
}
[Fact]
public async Task UpdateOneAsyncWithUpdateDefinition()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = MongoDB.Driver.Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = await SUT.UpdateOneAsync<T, TKey>(document, updateDef);
// Assert
Assert.True(result);
var updatedDocument = SUT.GetById<T, TKey>(document.Id, PartitionKey);
Assert.True(null != updatedDocument);
Assert.True(childrenToAdd[0].Type == updatedDocument.Children[0].Type, GetTestName());
Assert.True(childrenToAdd[0].Value == updatedDocument.Children[0].Value, GetTestName());
Assert.True(childrenToAdd[1].Type == updatedDocument.Children[1].Type, GetTestName());
Assert.True(childrenToAdd[1].Value == updatedDocument.Children[1].Value, GetTestName());
}
[Fact]
public void UpdateOneWithUpdateDefinition()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = MongoDB.Driver.Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = SUT.UpdateOne<T, TKey>(document, updateDef);
// Assert
Assert.True(result);
var updatedDocument = SUT.GetById<T, TKey>(document.Id, PartitionKey);
Assert.True(null != updatedDocument);
Assert.True(childrenToAdd[0].Type == updatedDocument.Children[0].Type, GetTestName());
Assert.True(childrenToAdd[0].Value == updatedDocument.Children[0].Value, GetTestName());
Assert.True(childrenToAdd[1].Type == updatedDocument.Children[1].Type, GetTestName());
Assert.True(childrenToAdd[1].Value == updatedDocument.Children[1].Value, GetTestName());
}
#endregion Update One
#region Update Many
[Fact]
public async Task UpdateManyWithLinqFilterAsync()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T, TKey>(documents);
var docIds = documents.Select(u => u.Id).ToArray();
var content = GetContent();
// Act
var result = await SUT.UpdateManyAsync<T, TKey, string>(x => docIds.Contains(x.Id), x => x.SomeContent, content, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocument = SUT.GetAll<T, TKey>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocument.Count == 2);
Assert.True(updatedDocument.All(u => u.SomeContent == content), GetTestName());
}
[Fact]
public async Task UpdateManyWithFilterDefinitionAsync()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T, TKey>(documents);
var docIds = documents.Select(u => u.Id).ToArray();
var filterDefinition = Builders<T>.Filter.Where(x => docIds.Contains(x.Id));
var content = GetContent();
// Act
var result = await SUT.UpdateManyAsync<T, TKey, string>(filterDefinition, x => x.SomeContent, content, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocument = SUT.GetAll<T, TKey>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocument.Count == 2);
Assert.True(updatedDocument.All(u => u.SomeContent == content), GetTestName());
}
[Fact]
public async Task UpdateManyWithLinqFilterAndUpdateDefinitionAsync()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T, TKey>(documents);
var docIds = documents.Select(u => u.Id).ToArray();
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
var content = GetContent();
// Act
var result = await SUT.UpdateManyAsync<T, TKey>(x => docIds.Contains(x.Id), updateDef, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocuments = SUT.GetAll<T, TKey>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocuments.Count == 2);
updatedDocuments.ForEach(updatedDocument =>
{
Assert.True(childrenToAdd[0].Type == updatedDocument.Children[0].Type, GetTestName());
Assert.True(childrenToAdd[0].Value == updatedDocument.Children[0].Value, GetTestName());
Assert.True(childrenToAdd[1].Type == updatedDocument.Children[1].Type, GetTestName());
Assert.True(childrenToAdd[1].Value == updatedDocument.Children[1].Value, GetTestName());
});
}
[Fact]
public async Task UpdateManyWithFilterAndUpdateDefinitionsAsync()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T, TKey>(documents);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
var docIds = documents.Select(u => u.Id).ToArray();
var filterDefinition = Builders<T>.Filter.Where(x => docIds.Contains(x.Id));
var content = GetContent();
// Act
var result = await SUT.UpdateManyAsync<T, TKey>(filterDefinition, updateDef, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocuments = SUT.GetAll<T, TKey>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocuments.Count == 2);
updatedDocuments.ForEach(updatedDocument =>
{
Assert.True(childrenToAdd[0].Type == updatedDocument.Children[0].Type, GetTestName());
Assert.True(childrenToAdd[0].Value == updatedDocument.Children[0].Value, GetTestName());
Assert.True(childrenToAdd[1].Type == updatedDocument.Children[1].Type, GetTestName());
Assert.True(childrenToAdd[1].Value == updatedDocument.Children[1].Value, GetTestName());
});
}
[Fact]
public void UpdateManyWithLinqFilter()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T, TKey>(documents);
var docIds = documents.Select(u => u.Id).ToArray();
var content = GetContent();
// Act
var result = SUT.UpdateMany<T, TKey, string>(x => docIds.Contains(x.Id), x => x.SomeContent, content, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocument = SUT.GetAll<T, TKey>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocument.Count == 2);
Assert.True(updatedDocument.All(u => u.SomeContent == content), GetTestName());
}
[Fact]
public void UpdateManyWithFilterDefinition()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T, TKey>(documents);
var docIds = documents.Select(u => u.Id).ToArray();
var filterDefinition = Builders<T>.Filter.Where(x => docIds.Contains(x.Id));
var content = GetContent();
// Act
var result = SUT.UpdateMany<T, TKey, string>(filterDefinition, x => x.SomeContent, content, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocument = SUT.GetAll<T, TKey>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocument.Count == 2);
Assert.True(updatedDocument.All(u => u.SomeContent == content), GetTestName());
}
[Fact]
public void UpdateManyWithLinqFilterAndUpdateDefinition()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T, TKey>(documents);
var docIds = documents.Select(u => u.Id).ToArray();
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
var content = GetContent();
// Act
var result = SUT.UpdateMany<T, TKey>(x => docIds.Contains(x.Id), updateDef, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocuments = SUT.GetAll<T, TKey>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocuments.Count == 2);
updatedDocuments.ForEach(updatedDocument =>
{
Assert.True(childrenToAdd[0].Type == updatedDocument.Children[0].Type, GetTestName());
Assert.True(childrenToAdd[0].Value == updatedDocument.Children[0].Value, GetTestName());
Assert.True(childrenToAdd[1].Type == updatedDocument.Children[1].Type, GetTestName());
Assert.True(childrenToAdd[1].Value == updatedDocument.Children[1].Value, GetTestName());
});
}
[Fact]
public void UpdateManyWithFilterAndUpdateDefinitions()
{
// Arrange
var documents = CreateTestDocuments(2);
SUT.AddMany<T, TKey>(documents);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
var docIds = documents.Select(u => u.Id).ToArray();
var filterDefinition = Builders<T>.Filter.Where(x => docIds.Contains(x.Id));
var content = GetContent();
// Act
var result = SUT.UpdateMany<T, TKey>(filterDefinition, updateDef, PartitionKey);
// Assert
Assert.True(result == 2, GetTestName());
var updatedDocuments = SUT.GetAll<T, TKey>(x => docIds.Contains(x.Id), PartitionKey);
Assert.True(updatedDocuments.Count == 2);
updatedDocuments.ForEach(updatedDocument =>
{
Assert.True(childrenToAdd[0].Type == updatedDocument.Children[0].Type, GetTestName());
Assert.True(childrenToAdd[0].Value == updatedDocument.Children[0].Value, GetTestName());
Assert.True(childrenToAdd[1].Type == updatedDocument.Children[1].Type, GetTestName());
Assert.True(childrenToAdd[1].Value == updatedDocument.Children[1].Value, GetTestName());
});
}
#endregion Update Many
}
}
@@ -0,0 +1,53 @@
using MongoDbGenericRepository;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
namespace CoreIntegrationTests.Infrastructure
{
public class MongoDbTestFixture<T, TKey> : IDisposable
where T : IDocument<TKey>, new()
where TKey : IEquatable<TKey>
{
public IMongoDbContext Context;
public MongoDbTestFixture()
{
}
public string PartitionKey { get; set; }
public static ConcurrentBag<T> DocsToDelete { get; set; } = new ConcurrentBag<T>();
public virtual void Dispose()
{
if (DocsToDelete.Any())
{
TestRepository.Instance.DeleteMany<T, TKey>(DocsToDelete.ToList());
}
}
public T CreateTestDocument()
{
var doc = new T();
DocsToDelete.Add(doc);
return doc;
}
public List<T> CreateTestDocuments(int numberOfDocumentsToCreate)
{
var docs = new List<T>();
for (var i = 0; i < numberOfDocumentsToCreate; i++)
{
var doc = new T();
docs.Add(doc);
DocsToDelete.Add(doc);
}
return docs;
}
}
}
@@ -0,0 +1,61 @@
using System;
namespace CoreIntegrationTests.Infrastructure
{
// Thanks BlueRaja - Danny Pflughoeft https://stackoverflow.com/a/13095144/5103354
/// <summary>
/// Extensions for the random number generator <see cref="Random"/>
/// </summary>
public static class RandomExtensions
{
/// <summary>
/// Returns a random long from min (inclusive) to max (exclusive)
/// </summary>
/// <param name="random">The given random instance</param>
/// <param name="min">The inclusive minimum bound</param>
/// <param name="max">The exclusive maximum bound. Must be greater than min</param>
public static long NextLong(this Random random, long min, long max)
{
if (max <= min)
throw new ArgumentOutOfRangeException("max", "max must be > min!");
//Working with ulong so that modulo works correctly with values > long.MaxValue
ulong uRange = (ulong)(max - min);
//Prevent a modulo bias; see https://stackoverflow.com/a/10984975/238419
//for more information.
//In the worst case, the expected number of calls is 2 (though usually it's
//much closer to 1) so this loop doesn't really hurt performance at all.
ulong ulongRand;
do
{
byte[] buf = new byte[8];
random.NextBytes(buf);
ulongRand = (ulong)BitConverter.ToInt64(buf, 0);
} while (ulongRand > ulong.MaxValue - ((ulong.MaxValue % uRange) + 1) % uRange);
return (long)(ulongRand % uRange) + min;
}
/// <summary>
/// Returns a random long from 0 (inclusive) to max (exclusive)
/// </summary>
/// <param name="random">The given random instance</param>
/// <param name="max">The exclusive maximum bound. Must be greater than 0</param>
public static long NextLong(this Random random, long max)
{
return random.NextLong(0, max);
}
/// <summary>
/// Returns a random long over all possible values of long (except long.MaxValue, similar to
/// random.Next())
/// </summary>
/// <param name="random">The given random instance</param>
public static long NextLong(this Random random)
{
return random.NextLong(long.MinValue, long.MaxValue);
}
}
}
@@ -0,0 +1,104 @@
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDbGenericRepository.Models;
using MongoDbGenericRepository.Utils;
using System;
using System.Collections.Generic;
namespace CoreIntegrationTests.Infrastructure
{
public class ProjectedGroup
{
public int Key { get; set; }
public List<string> Content { get; set; }
}
public class MyTestProjection
{
public string SomeContent { get; set; }
public DateTime SomeDate { get; set; }
}
public class Nested
{
public DateTime SomeDate { get; set; }
[BsonRepresentation(BsonType.Decimal128)]
public decimal SomeAmount { get; set; }
}
public class Child
{
public Child(string type, string value)
{
Type = type;
Value = value;
}
public string Type { get; set; }
public string Value { get; set; }
}
public class TestDoc : Document
{
public TestDoc()
{
Version = 2;
Nested = new Nested
{
SomeDate = DateTime.UtcNow
};
Children = new List<Child>();
}
public int SomeValue { get; set; }
public string SomeContent { get; set; }
public string SomeContent2 { get; set; }
public string SomeContent3 { get; set; }
public int GroupingKey { get; set; }
public Nested Nested { get; set; }
public List<Child> Children { get; set; }
}
public class TestDoc<TKey> : IDocument<TKey>
where TKey : IEquatable<TKey>
{
[BsonId]
public TKey Id { get; set; }
public int Version { get; set; }
public TestDoc()
{
InitializeFields();
Version = 2;
Nested = new Nested
{
SomeDate = DateTime.UtcNow
};
Children = new List<Child>();
}
public int GroupingKey { get; set; }
public string SomeContent { get; set; }
public string SomeContent4 { get; set; }
public string SomeContent5 { get; set; }
public Nested Nested { get; set; }
public List<Child> Children { get; set; }
public TId Init<TId>()
{
return IdGenerator.GetId<TId>();
}
private void InitializeFields()
{
Id = Init<TKey>();
}
}
}
@@ -1,7 +1,43 @@
using MongoDbGenericRepository; using MongoDB.Bson;
using MongoDbGenericRepository;
using System;
namespace IntegrationTests.Infrastructure namespace CoreIntegrationTests.Infrastructure
{ {
public interface ITestRepository<TKey> : IBaseMongoRepository<TKey> where TKey : IEquatable<TKey>
{
void DropTestCollection<TDocument>();
void DropTestCollection<TDocument>(string partitionKey);
}
public class TestTKeyRepository<TKey> : BaseMongoRepository<TKey>, ITestRepository<TKey> where TKey : IEquatable<TKey>
{
const string connectionString = "mongodb://localhost:27017/MongoDbTests";
private static readonly ITestRepository<TKey> _instance = new TestTKeyRepository<TKey>(connectionString);
/// <inheritdoc />
private TestTKeyRepository(string connectionString) : base(connectionString)
{
}
public static ITestRepository<TKey> Instance
{
get
{
return _instance;
}
}
public void DropTestCollection<TDocument>()
{
MongoDbContext.DropCollection<TDocument>();
}
public void DropTestCollection<TDocument>(string partitionKey)
{
MongoDbContext.DropCollection<TDocument>(partitionKey);
}
}
/// <summary> /// <summary>
/// A singleton implementation of the TestRepository /// A singleton implementation of the TestRepository
/// </summary> /// </summary>
@@ -1,140 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using Xunit;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class ProjectTestsPartitionedDocument : PartitionedDocument
{
public ProjectTestsPartitionedDocument() : base("TestPartitionKey")
{
Version = 2;
Nested = new Nested
{
SomeDate = DateTime.UtcNow
};
}
public string SomeContent { get; set; }
public Nested Nested { get; set; }
}
public class ProjectPartitionedTests : BaseMongoDbRepositoryTests<ProjectTestsPartitionedDocument>
{
[Fact]
public async Task PartitionedProjectOneAsync()
{
// Arrange
const string someContent = "ProjectOneAsyncContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocument();
document.SomeContent = someContent;
document.Nested.SomeDate = someDate;
SUT.AddOne(document);
// Act
var result = await SUT.ProjectOneAsync<ProjectTestsPartitionedDocument, MyProjection>(
x => x.Id == document.Id,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
},
PartitionKey);
// Assert
Assert.NotNull(result);
Assert.Equal(someContent, result.SomeContent);
Assert.Equal(someDate.Minute, result.SomeDate.Minute);
Assert.Equal(someDate.Second, result.SomeDate.Second);
}
[Fact]
public void PartitionedProjectOne()
{
// Arrange
const string someContent = "ProjectOneContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocument();
document.SomeContent = someContent;
document.Nested.SomeDate = someDate;
SUT.AddOne(document);
// Act
var result = SUT.ProjectOne<ProjectTestsPartitionedDocument, MyProjection>(
x => x.Id == document.Id,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
},
PartitionKey);
// Assert
Assert.NotNull(result);
Assert.Equal(someContent, result.SomeContent);
Assert.Equal(someDate.Minute, result.SomeDate.Minute);
Assert.Equal(someDate.Second, result.SomeDate.Second);
}
[Fact]
public async Task PartitionedProjectManyAsync()
{
// Arrange
const string someContent = "ProjectManyAsyncContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocuments(5);
document.ForEach(e =>
{
e.SomeContent = someContent;
e.Nested.SomeDate = someDate;
});
SUT.AddMany(document);
// Act
var result = await SUT.ProjectManyAsync<ProjectTestsPartitionedDocument, MyProjection>(
x => x.SomeContent == someContent,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
},
PartitionKey);
// Assert
Assert.Equal(5, result.Count);
Assert.Equal(someContent, result.First().SomeContent);
Assert.Equal(someDate.Minute, result.First().SomeDate.Minute);
Assert.Equal(someDate.Second, result.First().SomeDate.Second);
}
[Fact]
public void PartitionedProjectMany()
{
// Arrange
const string someContent = "ProjectManyContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocuments(5);
document.ForEach(e =>
{
e.SomeContent = someContent;
e.Nested.SomeDate = someDate;
});
SUT.AddMany(document);
// Act
var result = SUT.ProjectMany<ProjectTestsPartitionedDocument, MyProjection>(
x => x.SomeContent == someContent,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
},
PartitionKey);
// Assert
Assert.Equal(5, result.Count);
Assert.Equal(someContent, result.First().SomeContent);
Assert.Equal(someDate.Minute, result.First().SomeDate.Minute);
Assert.Equal(someDate.Second, result.First().SomeDate.Second);
}
}
}
-149
View File
@@ -1,149 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using Xunit;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class Nested
{
public DateTime SomeDate { get; set; }
}
public class MyProjection
{
public DateTime SomeDate { get; set; }
public string SomeContent { get; set; }
}
public class ProjectTestsDocument : Document
{
public ProjectTestsDocument()
{
Version = 2;
Nested = new Nested
{
SomeDate = DateTime.UtcNow
};
}
public string SomeContent { get; set; }
public Nested Nested { get; set; }
}
public class ProjectTests : BaseMongoDbRepositoryTests<ProjectTestsDocument>
{
[Fact]
public async Task ProjectOneAsync()
{
// Arrange
const string someContent = "ProjectOneAsyncContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocument();
document.SomeContent = someContent;
document.Nested.SomeDate = someDate;
SUT.AddOne(document);
// Act
var result = await SUT.ProjectOneAsync<ProjectTestsDocument, MyProjection>(
x => x.Id == document.Id,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
});
// Assert
Assert.NotNull(result);
Assert.Equal(someContent, result.SomeContent);
Assert.Equal(someDate.Minute, result.SomeDate.Minute);
Assert.Equal(someDate.Second, result.SomeDate.Second);
}
[Fact]
public void ProjectOne()
{
// Arrange
const string someContent = "ProjectOneContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocument();
document.SomeContent = someContent;
document.Nested.SomeDate = someDate;
SUT.AddOne(document);
// Act
var result = SUT.ProjectOne<ProjectTestsDocument, MyProjection>(
x => x.Id == document.Id,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
});
// Assert
Assert.NotNull(result);
Assert.Equal(someContent, result.SomeContent);
Assert.Equal(someDate.Minute, result.SomeDate.Minute);
Assert.Equal(someDate.Second, result.SomeDate.Second);
}
[Fact]
public async Task ProjectManyAsync()
{
// Arrange
const string someContent = "ProjectManyAsyncContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocuments(5);
document.ForEach(e =>
{
e.SomeContent = someContent;
e.Nested.SomeDate = someDate;
});
SUT.AddMany(document);
// Act
var result = await SUT.ProjectManyAsync<ProjectTestsDocument, MyProjection>(
x => x.SomeContent == someContent,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
});
// Assert
Assert.Equal(5, result.Count);
Assert.Equal(someContent, result.First().SomeContent);
Assert.Equal(someDate.Minute, result.First().SomeDate.Minute);
Assert.Equal(someDate.Second, result.First().SomeDate.Second);
}
[Fact]
public void ProjectMany()
{
// Arrange
const string someContent = "ProjectManyContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocuments(5);
document.ForEach(e =>
{
e.SomeContent = someContent;
e.Nested.SomeDate = someDate;
});
SUT.AddMany(document);
// Act
var result = SUT.ProjectMany<ProjectTestsDocument, MyProjection>(
x => x.SomeContent == someContent,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
});
// Assert
Assert.Equal(5, result.Count);
Assert.Equal(someContent, result.First().SomeContent);
Assert.Equal(someDate.Minute, result.First().SomeDate.Minute);
Assert.Equal(someDate.Second, result.First().SomeDate.Second);
}
}
}
@@ -1,181 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using Xunit;
using System;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class ReadTestsPartitionedDocument : PartitionedDocument
{
public ReadTestsPartitionedDocument() : base("TestPartitionKey")
{
Version = 1;
}
public string SomeContent { get; set; }
}
public class ReadPartitionedTests : BaseMongoDbRepositoryTests<ReadTestsPartitionedDocument>
{
[Fact]
public async Task PartitionedGetByIdAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.GetByIdAsync<ReadTestsPartitionedDocument>(document.Id, PartitionKey);
// Assert
Assert.NotNull(result);
}
[Fact]
public void PartitionedGetById()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.GetById<ReadTestsPartitionedDocument>(document.Id, PartitionKey);
// Assert
Assert.NotNull(result);
}
[Fact]
public async Task PartitionedGetOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.GetOneAsync<ReadTestsPartitionedDocument>(x => x.Id == document.Id, PartitionKey);
// Assert
Assert.NotNull(result);
}
[Fact]
public void PartitionedGetOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.GetOne<ReadTestsPartitionedDocument>(x => x.Id == document.Id, PartitionKey);
// Assert
Assert.NotNull(result);
}
[Fact]
public void PartitionedGetCursor()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var cursor = SUT.GetCursor<ReadTestsPartitionedDocument>(x => x.Id == document.Id, PartitionKey);
var count = cursor.Count();
// Assert
Assert.Equal(1, count);
}
[Fact]
public async Task PartitionedAnyAsyncReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.AnyAsync<ReadTestsPartitionedDocument>(x => x.Id == document.Id, PartitionKey);
// Assert
Assert.True(result);
}
[Fact]
public async Task PartitionedAnyAsyncReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.AnyAsync<ReadTestsPartitionedDocument>(x => x.Id == Guid.NewGuid(), PartitionKey);
// Assert
Assert.False(result);
}
[Fact]
public void PartitionedAnyReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.Any<ReadTestsPartitionedDocument>(x => x.Id == document.Id, PartitionKey);
// Assert
Assert.True(result);
}
[Fact]
public void PartitionedAnyReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.Any<ReadTestsPartitionedDocument>(x => x.Id == Guid.NewGuid(), PartitionKey);
// Assert
Assert.False(result);
}
[Fact]
public async Task PartitionedGetAllAsync()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "GetAllAsyncContent");
SUT.AddMany(documents);
// Act
var result = await SUT.GetAllAsync<ReadTestsPartitionedDocument>(x => x.SomeContent == "GetAllAsyncContent", PartitionKey);
// Assert
Assert.Equal(5, result.Count);
}
[Fact]
public void PartitionedGetAll()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "GetAllContent");
SUT.AddMany(documents);
// Act
var result = SUT.GetAll<ReadTestsPartitionedDocument>(x => x.SomeContent == "GetAllContent", PartitionKey);
// Assert
Assert.Equal(5, result.Count);
}
[Fact]
public async Task PartitionedCountAsync()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "CountAsyncContent");
SUT.AddMany(documents);
// Act
var result = await SUT.CountAsync<ReadTestsPartitionedDocument>(x => x.SomeContent == "CountAsyncContent", PartitionKey);
// Assert
Assert.Equal(5, result);
}
[Fact]
public void PartitionedCount()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "CountContent");
SUT.AddMany(documents);
// Act
var result = SUT.Count<ReadTestsPartitionedDocument>(x => x.SomeContent == "CountContent", PartitionKey);
// Assert
Assert.Equal(5, result);
}
}
}
-181
View File
@@ -1,181 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using Xunit;
using System;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class ReadTestsDocument : Document
{
public ReadTestsDocument()
{
Version = 2;
}
public string SomeContent { get; set; }
}
public class ReadTests : BaseMongoDbRepositoryTests<ReadTestsDocument>
{
[Fact]
public async Task GetByIdAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.GetByIdAsync<ReadTestsDocument>(document.Id);
// Assert
Assert.NotNull(result);
}
[Fact]
public void GetById()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.GetById<ReadTestsDocument>(document.Id);
// Assert
Assert.NotNull(result);
}
[Fact]
public async Task GetOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.GetOneAsync<ReadTestsDocument>(x => x.Id == document.Id);
// Assert
Assert.NotNull(result);
}
[Fact]
public void GetOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.GetOne<ReadTestsDocument>(x => x.Id == document.Id);
// Assert
Assert.NotNull(result);
}
[Fact]
public void GetCursor()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var cursor = SUT.GetCursor<ReadTestsDocument>(x => x.Id == document.Id);
var count = cursor.Count();
// Assert
Assert.Equal(1, count);
}
[Fact]
public async Task AnyAsyncReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.AnyAsync<ReadTestsDocument>(x => x.Id == document.Id);
// Assert
Assert.True(result);
}
[Fact]
public async Task AnyAsyncReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.AnyAsync<ReadTestsDocument>(x => x.Id == Guid.NewGuid());
// Assert
Assert.False(result);
}
[Fact]
public void AnyReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.Any<ReadTestsDocument>(x => x.Id == document.Id);
// Assert
Assert.True(result);
}
[Fact]
public void AnyReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.Any<ReadTestsDocument>(x => x.Id == Guid.NewGuid());
// Assert
Assert.False(result);
}
[Fact]
public async Task GetAllAsync()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "GetAllAsyncContent");
SUT.AddMany(documents);
// Act
var result = await SUT.GetAllAsync<ReadTestsDocument>(x => x.SomeContent == "GetAllAsyncContent");
// Assert
Assert.Equal(5, result.Count);
}
[Fact]
public void GetAll()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "GetAllContent");
SUT.AddMany(documents);
// Act
var result = SUT.GetAll<ReadTestsDocument>(x => x.SomeContent == "GetAllContent");
// Assert
Assert.Equal(5, result.Count);
}
[Fact]
public async Task CountAsync()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "CountAsyncContent");
SUT.AddMany(documents);
// Act
var result = await SUT.CountAsync<ReadTestsDocument>(x => x.SomeContent == "CountAsyncContent");
// Assert
Assert.Equal(5, result);
}
[Fact]
public void Count()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "CountContent");
SUT.AddMany(documents);
// Act
var result = SUT.Count<ReadTestsDocument>(x => x.SomeContent == "CountContent");
// Assert
Assert.Equal(5, result);
}
}
}
@@ -1,51 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using Xunit;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class UpdateTestsPartitionedDocument : PartitionedDocument
{
public UpdateTestsPartitionedDocument() : base("TestPartitionKey")
{
Version = 2;
}
public string SomeContent { get; set; }
}
public class UpdatePartitionedTests : BaseMongoDbRepositoryTests<UpdateTestsPartitionedDocument>
{
[Fact]
public void PartitionedUpdateOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
document.SomeContent = "UpdateOneContent";
// Act
var result = SUT.UpdateOne(document);
// Assert
Assert.True(result);
var updatedDocument = SUT.GetById<UpdateTestsPartitionedDocument>(document.Id, PartitionKey);
Assert.NotNull(updatedDocument);
Assert.Equal("UpdateOneContent", updatedDocument.SomeContent);
}
[Fact]
public async Task PartitionedUpdateOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
document.SomeContent = "UpdateOneAsyncContent";
// Act
var result = await SUT.UpdateOneAsync(document);
// Assert
Assert.True(result);
var updatedDocument = SUT.GetById<UpdateTestsPartitionedDocument>(document.Id, PartitionKey);
Assert.NotNull(updatedDocument);
Assert.Equal("UpdateOneAsyncContent", updatedDocument.SomeContent);
}
}
}
-51
View File
@@ -1,51 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using Xunit;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class UpdateTestsDocument : Document
{
public UpdateTestsDocument()
{
Version = 2;
}
public string SomeContent { get; set; }
}
public class UpdateTests : BaseMongoDbRepositoryTests<UpdateTestsDocument>
{
[Fact]
public void UpdateOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
document.SomeContent = "UpdateOneContent";
// Act
var result = SUT.UpdateOne(document);
// Assert
Assert.True(result);
var updatedDocument = SUT.GetById<UpdateTestsDocument>(document.Id);
Assert.NotNull(updatedDocument);
Assert.Equal("UpdateOneContent", updatedDocument.SomeContent);
}
[Fact]
public async Task UpdateOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
document.SomeContent = "UpdateOneAsyncContent";
// Act
var result = await SUT.UpdateOneAsync(document);
// Assert
Assert.True(result);
var updatedDocument = SUT.GetById<UpdateTestsDocument>(document.Id);
Assert.NotNull(updatedDocument);
Assert.Equal("UpdateOneAsyncContent", updatedDocument.SomeContent);
}
}
}
+1 -1
View File
@@ -11,7 +11,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" /> <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>
+19
View File
@@ -0,0 +1,19 @@
using IntegrationTests.Infrastructure;
using MongoDB.Bson;
using NUnit.Framework;
namespace IntegrationTests
{
public class ObjectIdTestDocument : TestDoc<ObjectId>
{
}
[TestFixture]
public class CRUDObjectIdTests : MongoDbTKeyDocumentTestBase<ObjectIdTestDocument, ObjectId>
{
public override string GetClassName()
{
return "CRUDObjectIdTests";
}
}
}
@@ -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<PartitionedCollectionNameDoc>
{
public override string GetClassName()
{
return "CRUDPartitionedCollectionNameAttributeTests";
}
}
}
+23
View File
@@ -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<PartitionedDoc>
{
public override string GetClassName()
{
return "CRUDPartitionedCollectionNameAttributeTests";
}
}
}
@@ -0,0 +1,26 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Attributes;
using MongoDbGenericRepository.Models;
using System;
namespace IntegrationTests
{
[CollectionName("TestingCollectionNameAttributePartitionedTKey")]
public class TKeyPartitionedCollectionNameDoc : TestDoc<Guid>, IPartitionedDocument
{
public TKeyPartitionedCollectionNameDoc()
{
PartitionKey = "TestPartitionKey";
}
public string PartitionKey { get; set; }
}
public class CRUDTKeyPartitionedCollectionNameAttributeTests : MongoDbTKeyDocumentTestBase<TKeyPartitionedCollectionNameDoc, Guid>
{
public override string GetClassName()
{
return "CRUDTKeyPartitionedCollectionNameAttributeTests";
}
}
}
@@ -0,0 +1,26 @@
using IntegrationTests.Infrastructure;
using MongoDB.Bson.Serialization.Attributes;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System;
namespace IntegrationTests
{
public class PartitionedTKeyTestDocument : TestDoc<Guid>, IPartitionedDocument
{
public PartitionedTKeyTestDocument()
{
PartitionKey = "TestPartitionKey";
}
public string PartitionKey { get; set; }
}
[TestFixture]
public class CRUDTKeyPartitionedTests : MongoDbTKeyDocumentTestBase<PartitionedTKeyTestDocument, Guid>
{
public override string GetClassName()
{
return "CRUDTKeyPartitionedTests";
}
}
}
+21
View File
@@ -0,0 +1,21 @@
using IntegrationTests.Infrastructure;
using MongoDB.Bson.Serialization.Attributes;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System;
namespace IntegrationTests
{
public class TKeyTestDocument : TestDoc<Guid>
{
}
[TestFixture]
public class CRUDTKeyTests : MongoDbTKeyDocumentTestBase<TKeyTestDocument, Guid>
{
public override string GetClassName()
{
return "CreateTKeyTests";
}
}
}
+18
View File
@@ -0,0 +1,18 @@
using IntegrationTests.Infrastructure;
using NUnit.Framework;
namespace IntegrationTests
{
public class TestDocument : TestDoc
{
}
[TestFixture]
public class CRUDTests : MongoDbDocumentTestBase<TestDocument>
{
public override string GetClassName()
{
return "CRUDTests";
}
}
}
@@ -1,68 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class CreateTestsPartitionedDocument : PartitionedDocument
{
public CreateTestsPartitionedDocument() : base("TestPartitionKey")
{
Version = 1;
}
public string SomeContent { get; set; }
}
public class CreatePartitionedTests : BaseMongoDbRepositoryTests<CreateTestsPartitionedDocument>
{
[Test]
public void PartitionedAddOne()
{
// Arrange
var document = new CreateTestsPartitionedDocument();
// Act
SUT.AddOne(document);
// Assert
long count = SUT.Count<CreateTestsPartitionedDocument>(e => e.Id == document.Id, PartitionKey);
Assert.AreEqual(1, count);
}
[Test]
public async Task PartitionedAddOneAsync()
{
// Arrange
var document = new CreateTestsPartitionedDocument();
// Act
await SUT.AddOneAsync(document);
// Assert
long count = SUT.Count<CreateTestsPartitionedDocument>(e => e.Id == document.Id, PartitionKey);
Assert.AreEqual(1, count);
}
[Test]
public void PartitionedAddMany()
{
// Arrange
var documents = new List<CreateTestsPartitionedDocument> { new CreateTestsPartitionedDocument(), new CreateTestsPartitionedDocument() };
// Act
SUT.AddMany(documents);
// Assert
long count = SUT.Count<CreateTestsPartitionedDocument>(e => e.Id == documents[0].Id || e.Id == documents[1].Id, PartitionKey);
Assert.AreEqual(2, count);
}
[Test]
public async Task PartitionedAddManyAsync()
{
// Arrange
var documents = new List<CreateTestsPartitionedDocument> { new CreateTestsPartitionedDocument(), new CreateTestsPartitionedDocument() };
// Act
await SUT.AddManyAsync(documents);
// Assert
long count = SUT.Count<CreateTestsPartitionedDocument>(e => e.Id == documents[0].Id || e.Id == documents[1].Id, PartitionKey);
Assert.AreEqual(2, count);
}
}
}
@@ -1,76 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDB.Bson.Serialization.Attributes;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class CreateTestsPartitionedTKeyDocument : IDocument<Guid>, IPartitionedDocument
{
[BsonId]
public Guid Id { get; set; }
public int Version { get; set; }
public CreateTestsPartitionedTKeyDocument()
{
Id = Guid.NewGuid();
Version = 2;
PartitionKey = "TestPartitionKey";
}
public string PartitionKey { get; set; }
public string SomeContent { get; set; }
}
public class CreatePartitionedTKeyTests : BaseMongoDbRepositoryTests<CreateTestsPartitionedTKeyDocument>
{
[Test]
public void PartitionedAddOne()
{
// Arrange
var document = new CreateTestsPartitionedTKeyDocument();
// Act
SUT.AddOne<CreateTestsPartitionedTKeyDocument, Guid>(document);
// Assert
long count = SUT.Count<CreateTestsPartitionedTKeyDocument, Guid>(e => e.Id == document.Id, PartitionKey);
Assert.AreEqual(1, count);
}
[Test]
public async Task PartitionedAddOneAsync()
{
// Arrange
var document = new CreateTestsPartitionedTKeyDocument();
// Act
await SUT.AddOneAsync<CreateTestsPartitionedTKeyDocument, Guid>(document);
// Assert
long count = SUT.Count<CreateTestsPartitionedTKeyDocument, Guid>(e => e.Id == document.Id, PartitionKey);
Assert.AreEqual(1, count);
}
[Test]
public void PartitionedAddMany()
{
// Arrange
var documents = new List<CreateTestsPartitionedTKeyDocument> { new CreateTestsPartitionedTKeyDocument(), new CreateTestsPartitionedTKeyDocument() };
// Act
SUT.AddMany<CreateTestsPartitionedTKeyDocument, Guid>(documents);
// Assert
long count = SUT.Count<CreateTestsPartitionedTKeyDocument, Guid>(e => e.Id == documents[0].Id || e.Id == documents[1].Id, PartitionKey);
Assert.AreEqual(2, count);
}
[Test]
public async Task PartitionedAddManyAsync()
{
// Arrange
var documents = new List<CreateTestsPartitionedTKeyDocument> { new CreateTestsPartitionedTKeyDocument(), new CreateTestsPartitionedTKeyDocument() };
// Act
await SUT.AddManyAsync<CreateTestsPartitionedTKeyDocument, Guid>(documents);
// Assert
long count = SUT.Count<CreateTestsPartitionedTKeyDocument, Guid>(e => e.Id == documents[0].Id || e.Id == documents[1].Id, PartitionKey);
Assert.AreEqual(2, count);
}
}
}
-75
View File
@@ -1,75 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDB.Bson.Serialization.Attributes;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class CreateTestsTKeyDocument : IDocument<Guid>
{
[BsonId]
public Guid Id { get; set; }
public int Version { get; set; }
public CreateTestsTKeyDocument()
{
Id = Guid.NewGuid();
Version = 2;
}
public string SomeContent { get; set; }
}
[TestFixture]
public class CreateTKeyTests : BaseMongoDbRepositoryTests<CreateTestsTKeyDocument>
{
[Test]
public void TKeyAddOne()
{
// Arrange
var document = new CreateTestsTKeyDocument();
// Act
SUT.AddOne<CreateTestsTKeyDocument, Guid>(document);
// Assert
long count = SUT.Count<CreateTestsTKeyDocument, Guid>(e => e.Id == document.Id);
Assert.AreEqual(1, count);
}
[Test]
public async Task TKeyAddOneAsync()
{
// Arrange
var document = new CreateTestsTKeyDocument();
// Act
await SUT.AddOneAsync<CreateTestsTKeyDocument, Guid>(document);
// Assert
long count = SUT.Count<CreateTestsTKeyDocument, Guid>(e => e.Id == document.Id);
Assert.AreEqual(1, count);
}
[Test]
public void TKeyAddMany()
{
// Arrange
var documents = new List<CreateTestsTKeyDocument> { new CreateTestsTKeyDocument(), new CreateTestsTKeyDocument() };
// Act
SUT.AddMany<CreateTestsTKeyDocument, Guid>(documents);
// Assert
long count = SUT.Count<CreateTestsTKeyDocument, Guid>(e => e.Id == documents[0].Id || e.Id == documents[1].Id);
Assert.AreEqual(2, count);
}
[Test]
public async Task TKeyAddManyAsync()
{
// Arrange
var documents = new List<CreateTestsTKeyDocument> { new CreateTestsTKeyDocument(), new CreateTestsTKeyDocument() };
// Act
await SUT.AddManyAsync<CreateTestsTKeyDocument, Guid>(documents);
// Assert
long count = SUT.Count<CreateTestsTKeyDocument, Guid>(e => e.Id == documents[0].Id || e.Id == documents[1].Id);
Assert.AreEqual(2, count);
}
}
}
-69
View File
@@ -1,69 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class CreateTestsDocument : Document
{
public CreateTestsDocument()
{
Version = 2;
}
public string SomeContent { get; set; }
}
[TestFixture]
public class CreateTests : BaseMongoDbRepositoryTests<CreateTestsDocument>
{
[Test]
public void AddOne()
{
// Arrange
var document = new CreateTestsDocument();
// Act
SUT.AddOne(document);
// Assert
long count = SUT.Count<CreateTestsDocument>(e => e.Id == document.Id);
Assert.AreEqual(1, count);
}
[Test]
public async Task AddOneAsync()
{
// Arrange
var document = new CreateTestsDocument();
// Act
await SUT.AddOneAsync(document);
// Assert
long count = SUT.Count<CreateTestsDocument>(e => e.Id == document.Id);
Assert.AreEqual(1, count);
}
[Test]
public void AddMany()
{
// Arrange
var documents = new List<CreateTestsDocument> { new CreateTestsDocument(), new CreateTestsDocument() };
// Act
SUT.AddMany(documents);
// Assert
long count = SUT.Count<CreateTestsDocument>(e => e.Id == documents[0].Id || e.Id == documents[1].Id);
Assert.AreEqual(2, count);
}
[Test]
public async Task AddManyAsync()
{
// Arrange
var documents = new List<CreateTestsDocument> { new CreateTestsDocument(), new CreateTestsDocument() };
// Act
await SUT.AddManyAsync(documents);
// Assert
long count = SUT.Count<CreateTestsDocument>(e => e.Id == documents[0].Id || e.Id == documents[1].Id);
Assert.AreEqual(2, count);
}
}
}
@@ -1,137 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDB.Bson.Serialization.Attributes;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class DeleteTestsPartitionedTKeyDocument : IPartitionedDocument, IDocument<Guid>
{
[BsonId]
public Guid Id { get; set; }
public int Version { get; set; }
public DeleteTestsPartitionedTKeyDocument()
{
Id = Guid.NewGuid();
Version = 2;
PartitionKey = "TestPartitionKey";
}
public string PartitionKey { get; set; }
public string SomeContent { get; set; }
}
public class DeletePartitionedTKeyTests : BaseMongoDbRepositoryTests<DeleteTestsPartitionedTKeyDocument>
{
[Test]
public void PartitionedDeleteOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<DeleteTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = SUT.DeleteOne<DeleteTestsPartitionedTKeyDocument, Guid>(document);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<DeleteTestsPartitionedTKeyDocument, Guid>(e => e.Id == document.Id, PartitionKey));
}
[Test]
public void PartitionedDeleteOneLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<DeleteTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = SUT.DeleteOne<DeleteTestsPartitionedTKeyDocument, Guid>(e => e.Id == document.Id, PartitionKey);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<DeleteTestsPartitionedTKeyDocument, Guid>(e => e.Id == document.Id, PartitionKey));
}
[Test]
public async Task PartitionedDeleteOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<DeleteTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = await SUT.DeleteOneAsync<DeleteTestsPartitionedTKeyDocument, Guid>(document);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<DeleteTestsPartitionedTKeyDocument, Guid>(e => e.Id == document.Id, PartitionKey));
}
[Test]
public async Task PartitionedDeleteOneAsyncLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<DeleteTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = await SUT.DeleteOneAsync<DeleteTestsPartitionedTKeyDocument, Guid>(e => e.Id == document.Id, PartitionKey);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<DeleteTestsPartitionedTKeyDocument, Guid>(e => e.Id == document.Id, PartitionKey));
}
[Test]
public async Task PartitionedDeleteManyAsyncLinq()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "DeleteManyAsyncLinqContent");
SUT.AddMany<DeleteTestsPartitionedTKeyDocument, Guid>(documents);
// Act
var result = await SUT.DeleteManyAsync<DeleteTestsPartitionedTKeyDocument, Guid>(e => e.SomeContent == "DeleteManyAsyncLinqContent", PartitionKey);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<DeleteTestsPartitionedTKeyDocument, Guid>(e => e.SomeContent == "DeleteManyAsyncLinqContent", PartitionKey));
}
[Test]
public async Task PartitionedDeleteManyAsync()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "DeleteManyAsyncLinqContent");
SUT.AddMany<DeleteTestsPartitionedTKeyDocument, Guid>(documents);
// Act
var result = await SUT.DeleteManyAsync<DeleteTestsPartitionedTKeyDocument, Guid>(documents);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<DeleteTestsPartitionedTKeyDocument, Guid>(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<DeleteTestsPartitionedTKeyDocument, Guid>(documents);
// Act
var result = SUT.DeleteMany<DeleteTestsPartitionedTKeyDocument, Guid>(e => e.SomeContent == content, PartitionKey);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<DeleteTestsPartitionedTKeyDocument, Guid>(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<DeleteTestsPartitionedTKeyDocument, Guid>(documents);
// Act
var result = SUT.DeleteMany<DeleteTestsPartitionedTKeyDocument, Guid>(documents);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<DeleteTestsPartitionedTKeyDocument, Guid>(e => e.SomeContent == content, PartitionKey));
}
}
}
-129
View File
@@ -1,129 +0,0 @@
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<DeleteTestsPartitionedDocument>
{
[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<DeleteTestsPartitionedDocument>(e => e.Id == document.Id, PartitionKey));
}
[Test]
public void PartitionedDeleteOneLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.DeleteOne<DeleteTestsPartitionedDocument>(e => e.Id == document.Id, PartitionKey);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<DeleteTestsPartitionedDocument>(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<DeleteTestsPartitionedDocument>(e => e.Id == document.Id, PartitionKey));
}
[Test]
public async Task PartitionedDeleteOneAsyncLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.DeleteOneAsync<DeleteTestsPartitionedDocument>(e => e.Id == document.Id, PartitionKey);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<DeleteTestsPartitionedDocument>(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<DeleteTestsPartitionedDocument>(e => e.SomeContent == "DeleteManyAsyncLinqContent", PartitionKey);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<DeleteTestsPartitionedDocument>(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<DeleteTestsPartitionedDocument>(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<DeleteTestsPartitionedDocument>(e => e.SomeContent == content, PartitionKey);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<DeleteTestsPartitionedDocument>(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<DeleteTestsPartitionedDocument>(e => e.SomeContent == content, PartitionKey));
}
}
}
-135
View File
@@ -1,135 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDB.Bson.Serialization.Attributes;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class DeleteTestsTKeyDocument : IDocument<Guid>
{
[BsonId]
public Guid Id { get; set; }
public int Version { get; set; }
public DeleteTestsTKeyDocument()
{
Id = Guid.NewGuid();
Version = 2;
}
public string SomeContent { get; set; }
}
public class DeleteTKeyTests : BaseMongoDbRepositoryTests<DeleteTestsTKeyDocument>
{
[Test]
public void DeleteOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<DeleteTestsTKeyDocument, Guid>(document);
// Act
var result = SUT.DeleteOne<DeleteTestsTKeyDocument, Guid>(document);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<DeleteTestsTKeyDocument, Guid>(e => e.Id == document.Id));
}
[Test]
public void DeleteOneLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<DeleteTestsTKeyDocument, Guid>(document);
// Act
var result = SUT.DeleteOne<DeleteTestsTKeyDocument, Guid>(e => e.Id == document.Id);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<DeleteTestsTKeyDocument, Guid>(e => e.Id == document.Id));
}
[Test]
public async Task DeleteOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<DeleteTestsTKeyDocument, Guid>(document);
// Act
var result = await SUT.DeleteOneAsync<DeleteTestsTKeyDocument, Guid>(document);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<DeleteTestsTKeyDocument, Guid>(e => e.Id == document.Id));
}
[Test]
public async Task DeleteOneAsyncLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<DeleteTestsTKeyDocument, Guid>(document);
// Act
var result = await SUT.DeleteOneAsync<DeleteTestsTKeyDocument, Guid>(e => e.Id == document.Id);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<DeleteTestsTKeyDocument, Guid>(e => e.Id == document.Id));
}
[Test]
public async Task DeleteManyAsyncLinq()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "DeleteManyAsyncLinqContent");
SUT.AddMany<DeleteTestsTKeyDocument, Guid>(documents);
// Act
var result = await SUT.DeleteManyAsync<DeleteTestsTKeyDocument, Guid>(e => e.SomeContent == "DeleteManyAsyncLinqContent");
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<DeleteTestsTKeyDocument, Guid>(e => e.SomeContent == "DeleteManyAsyncLinqContent"));
}
[Test]
public async Task DeleteManyAsync()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "DeleteManyAsyncLinqContent");
SUT.AddMany<DeleteTestsTKeyDocument, Guid>(documents);
// Act
var result = await SUT.DeleteManyAsync<DeleteTestsTKeyDocument, Guid>(documents);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<DeleteTestsTKeyDocument, Guid>(e => e.SomeContent == "DeleteManyAsyncLinqContent"));
}
[Test]
public void DeleteManyLinq()
{
// Arrange
var content = "DeleteManyLinqContent";
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = content);
SUT.AddMany<DeleteTestsTKeyDocument, Guid>(documents);
// Act
var result = SUT.DeleteMany<DeleteTestsTKeyDocument, Guid>(e => e.SomeContent == content);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<DeleteTestsTKeyDocument, Guid>(e => e.SomeContent == content));
}
[Test]
public void DeleteMany()
{
// Arrange
var content = "DeleteManyContent";
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = content);
SUT.AddMany<DeleteTestsTKeyDocument, Guid>(documents);
// Act
var result = SUT.DeleteMany<DeleteTestsTKeyDocument, Guid>(documents);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<DeleteTestsTKeyDocument, Guid>(e => e.SomeContent == content));
}
}
}
-129
View File
@@ -1,129 +0,0 @@
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<DeleteTestsDocument>
{
[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<DeleteTestsDocument>(e => e.Id == document.Id));
}
[Test]
public void DeleteOneLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.DeleteOne<DeleteTestsDocument>(e => e.Id == document.Id);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<DeleteTestsDocument>(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<DeleteTestsDocument>(e => e.Id == document.Id));
}
[Test]
public async Task DeleteOneAsyncLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.DeleteOneAsync<DeleteTestsDocument>(e => e.Id == document.Id);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<DeleteTestsDocument>(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<DeleteTestsDocument>(e => e.SomeContent == "DeleteManyAsyncLinqContent");
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<DeleteTestsDocument>(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<DeleteTestsDocument>(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<DeleteTestsDocument>(e => e.SomeContent == content);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<DeleteTestsDocument>(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<DeleteTestsDocument>(e => e.SomeContent == content));
}
}
}
@@ -1,108 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
namespace IntegrationTests.GroupTests
{
public class GroupingTestsDocument : Document
{
public GroupingTestsDocument()
{
Version = 2;
Children = new List<Child>();
}
public string SomeContent { get; set; }
public int GroupingKey { get; set; }
public List<Child> Children { get; set; }
}
public class ProjectedGroup
{
public int Key { get; set; }
public List<string> Content { get; set; }
}
public class GroupingTests : BaseMongoDbRepositoryTests<GroupingTestsDocument>
{
[Test]
public void GroupByTProjection()
{
// Arrange
var documents = CreateTestDocuments(5);
for(var i = 0; i < documents.Count - 2; i++)
{
documents[i].GroupingKey = 1;
documents[i].SomeContent = $"content-{i}";
}
for (var i = 3; i < documents.Count; i++)
{
documents[i].GroupingKey = 2;
documents[i].SomeContent = $"content-{i}";
}
SUT.AddMany(documents);
// Act
var result = SUT.GroupBy<GroupingTestsDocument, int, ProjectedGroup>(
e => e.GroupingKey, g => new ProjectedGroup {
Key = g.Key,
Content = g.Select(doc => doc.SomeContent).ToList()
});
// Assert
var key1Group = result.First(e => e.Key == 1);
Assert.NotNull(key1Group);
Assert.AreEqual(3, key1Group.Content.Count);
var key2Group = result.First(e => e.Key == 2);
Assert.NotNull(key2Group);
Assert.AreEqual(2, key2Group.Content.Count);
}
[Test]
public void FilteredGroupByTProjection()
{
// Arrange
var documents = CreateTestDocuments(5);
for (var i = 0; i < documents.Count - 2; i++)
{
documents[i].GroupingKey = 4;
documents[i].SomeContent = $"content-{i}";
}
for (var i = 3; i < documents.Count; i++)
{
documents[i].GroupingKey = 5;
documents[i].SomeContent = $"content-{i}";
}
var guid1 = Guid.NewGuid().ToString("n");
var guid2 = Guid.NewGuid().ToString("n");
for (var i = 0; i < documents.Count - 1; i++)
{
documents[i].Children = new List<Child> {
new Child(guid1, guid2)
};
}
SUT.AddMany(documents);
// Act
var result = SUT.GroupBy<GroupingTestsDocument, int, ProjectedGroup>(
e => e.Children.Any(c => c.Type == guid1),
e => e.GroupingKey, g => new ProjectedGroup
{
Key = g.Key,
Content = g.Select(doc => doc.SomeContent).ToList()
});
// Assert
var key1Group = result.First(e => e.Key == 4);
Assert.NotNull(key1Group);
Assert.AreEqual(3, key1Group.Content.Count);
var key2Group = result.First(e => e.Key == 5);
Assert.NotNull(key2Group);
Assert.AreEqual(1, key2Group.Content.Count);
}
}
}
-14
View File
@@ -1,14 +0,0 @@
namespace IntegrationTests.Infrastructure
{
public class Child
{
public Child(string type, string value)
{
Type = type;
Value = value;
}
public string Type { get; set; }
public string Value { get; set; }
}
}
@@ -0,0 +1,15 @@
using System;
namespace IntegrationTests.Infrastructure
{
/// <summary>
/// A class holding global variables.
/// </summary>
public static class GlobalVariables
{
/// <summary>
/// A random number generator.
/// </summary>
public static Random Random = new Random();
}
}
@@ -0,0 +1,821 @@
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
{
[TestFixture]
public abstract class MongoDbDocumentTestBase<T>
where T: TestDoc, new()
{
public T CreateTestDocument()
{
return new T();
}
public abstract string GetClassName();
public List<T> CreateTestDocuments(int numberOfDocumentsToCreate)
{
var docs = new List<T>();
for (var i = 0; i < numberOfDocumentsToCreate; i++)
{
docs.Add(new T());
}
return docs;
}
/// <summary>
/// The partition key for the collection, if any
/// </summary>
protected string PartitionKey { get; set; }
/// <summary>
/// the name of the test class
/// </summary>
protected string TestClassName { get; set; }
/// <summary>
/// The name of the document used for tests
/// </summary>
protected string DocumentTypeName { get; set; }
/// <summary>
/// SUT: System Under Test
/// </summary>
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<T>(PartitionKey);
}
else
{
SUT.DropTestCollection<T>();
}
}
#region Add
[Test]
public void AddOne()
{
// Arrange
var document = new T();
// Act
SUT.AddOne<T>(document);
// Assert
long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count<T>(e => e.Id.Equals(document.Id))
: SUT.Count<T>(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<T>(document);
// Assert
long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count<T>(e => e.Id.Equals(document.Id))
: SUT.Count<T>(e => e.Id.Equals(document.Id), PartitionKey);
Assert.AreEqual(1, count, GetTestName());
}
[Test]
public void AddMany()
{
// Arrange
var documents = new List<T> { new T(), new T() };
// Act
SUT.AddMany<T>(documents);
// Assert
long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count<T>(e => e.Id.Equals(documents[0].Id)
|| e.Id.Equals(documents[1].Id))
: SUT.Count<T>(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<T> { new T(), new T() };
// Act
await SUT.AddManyAsync<T>(documents);
// Assert
long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count<T>(e => e.Id.Equals(documents[0].Id)
|| e.Id.Equals(documents[1].Id))
: SUT.Count<T>(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<T>(document);
// Act
var result = await SUT.GetByIdAsync<T>(document.Id, PartitionKey);
// Assert
Assert.IsNotNull(result, GetTestName());
}
[Test]
public void GetById()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
// Act
var result = SUT.GetById<T>(document.Id, PartitionKey);
// Assert
Assert.IsNotNull(result, GetTestName());
}
[Test]
public async Task GetOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
// Act
var result = await SUT.GetOneAsync<T>(x => x.Id.Equals(document.Id), PartitionKey);
// Assert
Assert.IsNotNull(result, GetTestName());
}
[Test]
public void GetOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
// Act
var result = SUT.GetOne<T>(x => x.Id.Equals(document.Id), PartitionKey);
// Assert
Assert.IsNotNull(result, GetTestName());
}
[Test]
public void GetCursor()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
// Act
var cursor = SUT.GetCursor<T>(x => x.Id.Equals(document.Id), PartitionKey);
var count = cursor.CountDocuments();
// Assert
Assert.AreEqual(1, count, GetTestName());
}
[Test]
public async Task AnyAsyncReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
// Act
var result = await SUT.AnyAsync<T>(x => x.Id.Equals(document.Id), PartitionKey);
// Assert
Assert.AreEqual(true, result, GetTestName());
}
[Test]
public async Task AnyAsyncReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
// Act
var result = await SUT.AnyAsync<T>(x => x.Id.Equals(Guid.NewGuid()), PartitionKey);
// Assert
Assert.AreEqual(false, result, GetTestName());
}
[Test]
public void AnyReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
// Act
var result = SUT.Any<T>(x => x.Id.Equals(document.Id), PartitionKey);
// Assert
Assert.AreEqual(true, result, GetTestName());
}
[Test]
public void AnyReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
// Act
var result = SUT.Any<T>(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<T>(documents);
// Act
var result = await SUT.GetAllAsync<T>(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<T>(documents);
// Act
var result = SUT.GetAll<T>(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<T>(documents);
// Act
var result = await SUT.CountAsync<T>(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<T>(documents);
// Act
var result = SUT.Count<T>(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<T>(document);
var content = GetContent();
document.SomeContent = content;
// Act
var result = SUT.UpdateOne<T>(document);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<T>(document.Id, PartitionKey);
Assert.IsNotNull(updatedDocument, GetTestName());
Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName());
}
[Test]
public async Task UpdateOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
var content = GetContent();
document.SomeContent = content;
// Act
var result = await SUT.UpdateOneAsync<T>(document);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<T>(document.Id, PartitionKey);
Assert.IsNotNull(updatedDocument, GetTestName());
Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName());
}
[Test]
public void UpdateOneField()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
var content = GetContent();
// Act
var result = SUT.UpdateOne<T, string>(document, x => x.SomeContent, content);
// Assert
Assert.IsTrue(result, GetTestName());
var updatedDocument = SUT.GetById<T>(document.Id, PartitionKey);
Assert.IsNotNull(updatedDocument, GetTestName());
Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName());
}
[Test]
public async Task UpdateOneFieldAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
var content = GetContent();
// Act
var result = await SUT.UpdateOneAsync<T, string>(document, x => x.SomeContent, content);
// Assert
Assert.IsTrue(result, GetTestName());
var updatedDocument = SUT.GetById<T>(document.Id, PartitionKey);
Assert.IsNotNull(updatedDocument, GetTestName());
Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName());
}
[Test]
public void UpdateOneFieldWithFilter()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
var content = GetContent();
// Act
var result = SUT.UpdateOne<T, string>(x => x.Id.Equals(document.Id), x => x.SomeContent, content, PartitionKey);
// Assert
Assert.IsTrue(result, GetTestName());
var updatedDocument = SUT.GetById<T>(document.Id, PartitionKey);
Assert.IsNotNull(updatedDocument, GetTestName());
Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName());
}
[Test]
public async Task UpdateOneFieldWithFilterAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
var content = GetContent();
// Act
var result = await SUT.UpdateOneAsync<T, string>(x => x.Id.Equals(document.Id), x => x.SomeContent, content, PartitionKey);
// Assert
Assert.IsTrue(result, GetTestName());
var updatedDocument = SUT.GetById<T>(document.Id, PartitionKey);
Assert.IsNotNull(updatedDocument, GetTestName());
Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName());
}
[Test]
public async Task UpdateOneAsyncWithUpdateDefinition()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = MongoDB.Driver.Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = await SUT.UpdateOneAsync<T>(document, updateDef);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<T>(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<T>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = MongoDB.Driver.Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = SUT.UpdateOne<T>(document, updateDef);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<T>(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<T>(document);
// Act
var result = SUT.DeleteOne<T>(document);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<T>(e => e.Id.Equals(document.Id), PartitionKey), GetTestName());
}
[Test]
public void DeleteOneLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
// Act
var result = SUT.DeleteOne<T>(e => e.Id.Equals(document.Id), PartitionKey);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<T>(e => e.Id.Equals(document.Id), PartitionKey), GetTestName());
}
[Test]
public async Task DeleteOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
// Act
var result = await SUT.DeleteOneAsync<T>(document);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<T>(e => e.Id.Equals(document.Id), PartitionKey), GetTestName());
}
[Test]
public async Task DeleteOneAsyncLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T>(document);
// Act
var result = await SUT.DeleteOneAsync<T>(e => e.Id.Equals(document.Id), PartitionKey);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<T>(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<T>(documents);
// Act
var result = await SUT.DeleteManyAsync<T>(e => e.SomeContent == criteria, PartitionKey);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<T>(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<T>(documents);
// Act
var result = await SUT.DeleteManyAsync<T>(documents);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<T>(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<T>(documents);
// Act
var result = SUT.DeleteMany<T>(e => e.SomeContent == criteria, PartitionKey);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<T>(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<T>(documents);
// Act
var result = SUT.DeleteMany<T>(documents);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<T>(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<T>(document);
// Act
var result = await SUT.ProjectOneAsync<T, MyTestProjection>(
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<T>(document);
// Act
var result = SUT.ProjectOne<T, MyTestProjection>(
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<T>(documents);
// Act
var result = await SUT.ProjectManyAsync<T, MyTestProjection>(
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<T>(documents);
// Act
var result = SUT.ProjectMany<T, MyTestProjection>(
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 Group By
[Test]
public void GroupByTProjection()
{
// Arrange
var documents = CreateTestDocuments(5);
var content = GetContent();
for (var i = 0; i < documents.Count - 2; i++)
{
documents[i].GroupingKey = 1;
documents[i].SomeContent = $"{content}-{i}";
}
for (var i = 3; i < documents.Count; i++)
{
documents[i].GroupingKey = 2;
documents[i].SomeContent = $"{content}-{i}";
}
SUT.AddMany(documents);
// Act
var result = SUT.GroupBy<T, int, ProjectedGroup>(
e => e.GroupingKey, g => new ProjectedGroup
{
Key = g.Key,
Content = g.Select(doc => doc.SomeContent).ToList()
},
PartitionKey);
// Assert
var key1Group = result.First(e => e.Key == 1);
Assert.NotNull(key1Group);
Assert.AreEqual(3, key1Group.Content.Count);
var key2Group = result.First(e => e.Key == 2);
Assert.NotNull(key2Group);
Assert.AreEqual(2, key2Group.Content.Count);
}
[Test]
public void FilteredGroupByTProjection()
{
// Arrange
var documents = CreateTestDocuments(5);
var content = GetContent();
for (var i = 0; i < documents.Count - 2; i++)
{
documents[i].GroupingKey = 4;
documents[i].SomeContent = $"{content}-{i}";
}
for (var i = 3; i < documents.Count; i++)
{
documents[i].GroupingKey = 5;
documents[i].SomeContent = $"{content}-{i}";
}
var guid1 = Guid.NewGuid().ToString("n");
var guid2 = Guid.NewGuid().ToString("n");
for (var i = 0; i < documents.Count - 1; i++)
{
documents[i].Children = new List<Child> {
new Child(guid1, guid2)
};
}
SUT.AddMany(documents);
// Act
var result = SUT.GroupBy<T, int, ProjectedGroup>(
e => e.Children.Any(c => c.Type == guid1),
e => e.GroupingKey, g => new ProjectedGroup
{
Key = g.Key,
Content = g.Select(doc => doc.SomeContent).ToList()
}, PartitionKey);
// Assert
var key1Group = result.First(e => e.Key == 4);
Assert.NotNull(key1Group);
Assert.AreEqual(3, key1Group.Content.Count);
var key2Group = result.First(e => e.Key == 5);
Assert.NotNull(key2Group);
Assert.AreEqual(1, key2Group.Content.Count);
}
#endregion Group By
#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
}
}
@@ -0,0 +1,735 @@
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
{
[TestFixture]
public abstract class MongoDbTKeyDocumentTestBase<T, TKey>
where T: TestDoc<TKey>, new()
where TKey : IEquatable<TKey>
{
public T CreateTestDocument()
{
return new T();
}
public abstract string GetClassName();
public List<T> CreateTestDocuments(int numberOfDocumentsToCreate)
{
var docs = new List<T>();
for (var i = 0; i < numberOfDocumentsToCreate; i++)
{
docs.Add(new T());
}
return docs;
}
/// <summary>
/// The partition key for the collection, if any
/// </summary>
protected string PartitionKey { get; set; }
/// <summary>
/// the name of the test class
/// </summary>
protected string TestClassName { get; set; }
/// <summary>
/// The name of the document used for tests
/// </summary>
protected string DocumentTypeName { get; set; }
/// <summary>
/// SUT: System Under Test
/// </summary>
protected static ITestRepository SUT { get; set; }
public MongoDbTKeyDocumentTestBase()
{
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<T>(PartitionKey);
}
else
{
SUT.DropTestCollection<T>();
}
}
#region Add
[Test]
public void AddOne()
{
// Arrange
var document = new T();
// Act
SUT.AddOne<T, TKey>(document);
// Assert
long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count<T, TKey>(e => e.Id.Equals(document.Id))
: SUT.Count<T, TKey>(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<T, TKey>(document);
// Assert
long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count<T, TKey>(e => e.Id.Equals(document.Id))
: SUT.Count<T, TKey>(e => e.Id.Equals(document.Id), PartitionKey);
Assert.AreEqual(1, count, GetTestName());
}
[Test]
public void AddMany()
{
// Arrange
var documents = new List<T> { new T(), new T() };
// Act
SUT.AddMany<T, TKey>(documents);
// Assert
long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count<T, TKey>(e => e.Id.Equals(documents[0].Id)
|| e.Id.Equals(documents[1].Id))
: SUT.Count<T, TKey>(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<T> { new T(), new T() };
// Act
await SUT.AddManyAsync<T, TKey>(documents);
// Assert
long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count<T, TKey>(e => e.Id.Equals(documents[0].Id)
|| e.Id.Equals(documents[1].Id))
: SUT.Count<T, TKey>(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<T, TKey>(document);
// Act
var result = await SUT.GetByIdAsync<T, TKey>(document.Id, PartitionKey);
// Assert
Assert.IsNotNull(result, GetTestName());
}
[Test]
public void GetById()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
// Act
var result = SUT.GetById<T, TKey>(document.Id, PartitionKey);
// Assert
Assert.IsNotNull(result, GetTestName());
}
[Test]
public async Task GetOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
// Act
var result = await SUT.GetOneAsync<T, TKey>(x => x.Id.Equals(document.Id), PartitionKey);
// Assert
Assert.IsNotNull(result, GetTestName());
}
[Test]
public void GetOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
// Act
var result = SUT.GetOne<T, TKey>(x => x.Id.Equals(document.Id), PartitionKey);
// Assert
Assert.IsNotNull(result, GetTestName());
}
[Test]
public void GetCursor()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
// Act
var cursor = SUT.GetCursor<T, TKey>(x => x.Id.Equals(document.Id), PartitionKey);
var count = cursor.CountDocuments();
// Assert
Assert.AreEqual(1, count, GetTestName());
}
[Test]
public async Task AnyAsyncReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
// Act
var result = await SUT.AnyAsync<T, TKey>(x => x.Id.Equals(document.Id), PartitionKey);
// Assert
Assert.AreEqual(true, result, GetTestName());
}
[Test]
public async Task AnyAsyncReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
// Act
var result = await SUT.AnyAsync<T, TKey>(x => x.Id.Equals(document.Init<TKey>()), PartitionKey);
// Assert
Assert.AreEqual(false, result, GetTestName());
}
[Test]
public void AnyReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
// Act
var result = SUT.Any<T, TKey>(x => x.Id.Equals(document.Id), PartitionKey);
// Assert
Assert.AreEqual(true, result, GetTestName());
}
[Test]
public void AnyReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
// Act
var result = SUT.Any<T, TKey>(x => x.Id.Equals(document.Init<TKey>()), 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<T, TKey>(documents);
// Act
var result = await SUT.GetAllAsync<T, TKey>(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<T, TKey>(documents);
// Act
var result = SUT.GetAll<T, TKey>(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<T, TKey>(documents);
// Act
var result = await SUT.CountAsync<T, TKey>(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<T, TKey>(documents);
// Act
var result = SUT.Count<T, TKey>(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<T, TKey>(document);
var content = GetContent();
document.SomeContent = content;
// Act
var result = SUT.UpdateOne<T, TKey>(document);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<T, TKey>(document.Id, PartitionKey);
Assert.IsNotNull(updatedDocument, GetTestName());
Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName());
}
[Test]
public async Task UpdateOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
var content = GetContent();
document.SomeContent = content;
// Act
var result = await SUT.UpdateOneAsync<T, TKey>(document);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<T, TKey>(document.Id, PartitionKey);
Assert.IsNotNull(updatedDocument, GetTestName());
Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName());
}
[Test]
public void UpdateOneField()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
var content = GetContent();
// Act
var result = SUT.UpdateOne<T, TKey, string>(document, x => x.SomeContent, content);
// Assert
Assert.IsTrue(result, GetTestName());
var updatedDocument = SUT.GetById<T, TKey>(document.Id, PartitionKey);
Assert.IsNotNull(updatedDocument, GetTestName());
Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName());
}
[Test]
public async Task UpdateOneFieldAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
var content = GetContent();
// Act
var result = await SUT.UpdateOneAsync<T, TKey, string>(document, x => x.SomeContent, content);
// Assert
Assert.IsTrue(result, GetTestName());
var updatedDocument = SUT.GetById<T, TKey>(document.Id, PartitionKey);
Assert.IsNotNull(updatedDocument, GetTestName());
Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName());
}
[Test]
public void UpdateOneFieldWithFilter()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
var content = GetContent();
// Act
var result = SUT.UpdateOne<T, TKey, string>(x => x.Id.Equals(document.Id), x => x.SomeContent, content, PartitionKey);
// Assert
Assert.IsTrue(result, GetTestName());
var updatedDocument = SUT.GetById<T, TKey>(document.Id, PartitionKey);
Assert.IsNotNull(updatedDocument, GetTestName());
Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName());
}
[Test]
public async Task UpdateOneFieldWithFilterAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
var content = GetContent();
// Act
var result = await SUT.UpdateOneAsync<T, TKey, string>(x => x.Id.Equals(document.Id), x => x.SomeContent, content, PartitionKey);
// Assert
Assert.IsTrue(result, GetTestName());
var updatedDocument = SUT.GetById<T, TKey>(document.Id, PartitionKey);
Assert.IsNotNull(updatedDocument, GetTestName());
Assert.AreEqual(content, updatedDocument.SomeContent, GetTestName());
}
[Test]
public async Task UpdateOneAsyncWithUpdateDefinition()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = MongoDB.Driver.Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = await SUT.UpdateOneAsync<T, TKey>(document, updateDef);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<T, TKey>(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<T, TKey>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = MongoDB.Driver.Builders<T>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = SUT.UpdateOne<T, TKey>(document, updateDef);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<T, TKey>(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<T, TKey>(document);
// Act
var result = SUT.DeleteOne<T, TKey>(document);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<T, TKey>(e => e.Id.Equals(document.Id), PartitionKey), GetTestName());
}
[Test]
public void DeleteOneLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
// Act
var result = SUT.DeleteOne<T, TKey>(e => e.Id.Equals(document.Id), PartitionKey);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<T, TKey>(e => e.Id.Equals(document.Id), PartitionKey), GetTestName());
}
[Test]
public async Task DeleteOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
// Act
var result = await SUT.DeleteOneAsync<T, TKey>(document);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<T, TKey>(e => e.Id.Equals(document.Id), PartitionKey), GetTestName());
}
[Test]
public async Task DeleteOneAsyncLinq()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<T, TKey>(document);
// Act
var result = await SUT.DeleteOneAsync<T, TKey>(e => e.Id.Equals(document.Id), PartitionKey);
// Assert
Assert.AreEqual(1, result);
Assert.IsFalse(SUT.Any<T, TKey>(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<T, TKey>(documents);
// Act
var result = await SUT.DeleteManyAsync<T, TKey>(e => e.SomeContent == criteria, PartitionKey);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<T, TKey>(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<T, TKey>(documents);
// Act
var result = await SUT.DeleteManyAsync<T, TKey>(documents);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<T, TKey>(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<T, TKey>(documents);
// Act
var result = SUT.DeleteMany<T, TKey>(e => e.SomeContent == criteria, PartitionKey);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<T, TKey>(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<T, TKey>(documents);
// Act
var result = SUT.DeleteMany<T, TKey>(documents);
// Assert
Assert.AreEqual(5, result);
Assert.IsFalse(SUT.Any<T, TKey>(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<T, TKey>(document);
// Act
var result = await SUT.ProjectOneAsync<T, MyTestProjection, TKey>(
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<T, TKey>(document);
// Act
var result = SUT.ProjectOne<T, MyTestProjection, TKey>(
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<T, TKey>(documents);
// Act
var result = await SUT.ProjectManyAsync<T, MyTestProjection, TKey>(
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<T, TKey>(documents);
// Act
var result = SUT.ProjectMany<T, MyTestProjection, TKey>(
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
}
}
@@ -0,0 +1,61 @@
using System;
namespace IntegrationTests.Infrastructure
{
// Thanks BlueRaja - Danny Pflughoeft https://stackoverflow.com/a/13095144/5103354
/// <summary>
/// Extensions for the random number generator <see cref="Random"/>
/// </summary>
public static class RandomExtensions
{
/// <summary>
/// Returns a random long from min (inclusive) to max (exclusive)
/// </summary>
/// <param name="random">The given random instance</param>
/// <param name="min">The inclusive minimum bound</param>
/// <param name="max">The exclusive maximum bound. Must be greater than min</param>
public static long NextLong(this Random random, long min, long max)
{
if (max <= min)
throw new ArgumentOutOfRangeException("max", "max must be > min!");
//Working with ulong so that modulo works correctly with values > long.MaxValue
ulong uRange = (ulong)(max - min);
//Prevent a modulo bias; see https://stackoverflow.com/a/10984975/238419
//for more information.
//In the worst case, the expected number of calls is 2 (though usually it's
//much closer to 1) so this loop doesn't really hurt performance at all.
ulong ulongRand;
do
{
byte[] buf = new byte[8];
random.NextBytes(buf);
ulongRand = (ulong)BitConverter.ToInt64(buf, 0);
} while (ulongRand > ulong.MaxValue - ((ulong.MaxValue % uRange) + 1) % uRange);
return (long)(ulongRand % uRange) + min;
}
/// <summary>
/// Returns a random long from 0 (inclusive) to max (exclusive)
/// </summary>
/// <param name="random">The given random instance</param>
/// <param name="max">The exclusive maximum bound. Must be greater than 0</param>
public static long NextLong(this Random random, long max)
{
return random.NextLong(0, max);
}
/// <summary>
/// Returns a random long over all possible values of long (except long.MaxValue, similar to
/// random.Next())
/// </summary>
/// <param name="random">The given random instance</param>
public static long NextLong(this Random random)
{
return random.NextLong(long.MinValue, long.MaxValue);
}
}
}
@@ -0,0 +1,94 @@
using MongoDB.Bson.Serialization.Attributes;
using MongoDbGenericRepository.Models;
using MongoDbGenericRepository.Utils;
using System;
using System.Collections.Generic;
namespace IntegrationTests.Infrastructure
{
public class ProjectedGroup
{
public int Key { get; set; }
public List<string> Content { get; set; }
}
public class MyTestProjection
{
public string SomeContent { get; set; }
public DateTime SomeDate { get; set; }
}
public class Nested
{
public DateTime SomeDate { get; set; }
}
public class Child
{
public Child(string type, string value)
{
Type = type;
Value = value;
}
public string Type { get; set; }
public string Value { get; set; }
}
public class TestDoc : Document
{
public TestDoc()
{
Version = 2;
Nested = new Nested
{
SomeDate = DateTime.UtcNow
};
Children = new List<Child>();
}
public string SomeContent { get; set; }
public int GroupingKey { get; set; }
public Nested Nested { get; set; }
public List<Child> Children { get; set; }
}
public class TestDoc<TKey> : IDocument<TKey>
where TKey : IEquatable<TKey>
{
[BsonId]
public TKey Id { get; set; }
public int Version { get; set; }
public TestDoc()
{
InitializeFields();
Version = 2;
Nested = new Nested
{
SomeDate = DateTime.UtcNow
};
Children = new List<Child>();
}
public string SomeContent { get; set; }
public Nested Nested { get; set; }
public List<Child> Children { get; set; }
public TId Init<TId>()
{
return IdGenerator.GetId<TId>();
}
private void InitializeFields()
{
Id = Init<TKey>();
}
}
}
@@ -1,4 +1,9 @@
using MongoDbGenericRepository; using MongoDB.Driver;
using MongoDbGenericRepository;
using MongoDbGenericRepository.Models;
using System;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace IntegrationTests.Infrastructure namespace IntegrationTests.Infrastructure
{ {
@@ -18,5 +23,20 @@ namespace IntegrationTests.Infrastructure
{ {
MongoDbContext.DropCollection<TDocument>(partitionKey); MongoDbContext.DropCollection<TDocument>(partitionKey);
} }
/// <summary>
/// Gets the max of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <returns></returns>
public async Task<TDocument> GetByMaxAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, object>> orderByDescending)
where TDocument : IDocument<TKey>
where TKey : System.IEquatable<TKey>
{
return await GetCollection<TDocument, TKey>().Find(Builders<TDocument>.Filter.Where(filter))
.SortByDescending(orderByDescending)
.FirstOrDefaultAsync();
}
} }
} }
+49 -36
View File
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" />
<Import Project="..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -11,6 +13,8 @@
<AssemblyName>IntegrationTests</AssemblyName> <AssemblyName>IntegrationTests</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -30,54 +34,63 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="MongoDB.Bson, Version=2.4.4.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="Crc32C.NET, Version=1.0.5.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MongoDB.Bson.2.4.4\lib\net45\MongoDB.Bson.dll</HintPath> <HintPath>..\packages\Crc32C.NET.1.0.5.0\lib\net20\Crc32C.NET.dll</HintPath>
</Reference> </Reference>
<Reference Include="MongoDB.Driver, Version=2.4.4.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="DnsClient, Version=1.2.0.0, Culture=neutral, PublicKeyToken=4574bb5573c51424, processorArchitecture=MSIL">
<HintPath>..\packages\MongoDB.Driver.2.4.4\lib\net45\MongoDB.Driver.dll</HintPath> <HintPath>..\packages\DnsClient.1.2.0\lib\net45\DnsClient.dll</HintPath>
</Reference> </Reference>
<Reference Include="MongoDB.Driver.Core, Version=2.4.4.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="MongoDB.Bson, Version=2.9.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MongoDB.Driver.Core.2.4.4\lib\net45\MongoDB.Driver.Core.dll</HintPath> <HintPath>..\packages\MongoDB.Bson.2.9.3\lib\net452\MongoDB.Bson.dll</HintPath>
</Reference> </Reference>
<Reference Include="nunit.framework, Version=3.7.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL"> <Reference Include="MongoDB.Driver, Version=2.9.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.7.1\lib\net45\nunit.framework.dll</HintPath> <HintPath>..\packages\MongoDB.Driver.2.9.3\lib\net452\MongoDB.Driver.dll</HintPath>
</Reference>
<Reference Include="MongoDB.Driver.Core, Version=2.9.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MongoDB.Driver.Core.2.9.3\lib\net452\MongoDB.Driver.Core.dll</HintPath>
</Reference>
<Reference Include="MongoDbGenericRepository, Version=1.4.5.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MongoDbGenericRepository.1.4.5\lib\net452\MongoDbGenericRepository.dll</HintPath>
</Reference>
<Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="SharpCompress, Version=0.23.0.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
<HintPath>..\packages\SharpCompress.0.23.0\lib\net45\SharpCompress.dll</HintPath>
</Reference>
<Reference Include="Snappy.NET, Version=1.1.1.8, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Snappy.NET.1.1.1.8\lib\net45\Snappy.NET.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath> <HintPath>..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
<Private>True</Private> <Private>True</Private>
<Private>True</Private>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="CreateTKeyPartitionedTests.cs" /> <Compile Include="CRUDObjectIdTests.cs" />
<Compile Include="CreateTKeyTests.cs" /> <Compile Include="CRUDPartitionedTests.cs" />
<Compile Include="DeletePartitionedTKeyTests.cs" /> <Compile Include="CRUDTKeyPartitionedCollectionNameAttributeTests.cs" />
<Compile Include="DeletePartitionedTests.cs" /> <Compile Include="CRUDTests.cs" />
<Compile Include="DeleteTKeyTests.cs" /> <Compile Include="CRUDPartitionedCollectionNameAttributeTests.cs" />
<Compile Include="DeleteTests.cs" /> <Compile Include="CRUDTKeyPartitionedTests.cs" />
<Compile Include="GroupTests\GroupingTests.cs" /> <Compile Include="CRUDTKeyTests.cs" />
<Compile Include="Infrastructure\BaseMongoDbRepositoryTests.cs" /> <Compile Include="Infrastructure\BaseMongoDbRepositoryTests.cs" />
<Compile Include="CreatePartitionedTests.cs" /> <Compile Include="Infrastructure\GlobalVariables.cs" />
<Compile Include="Infrastructure\Child.cs" />
<Compile Include="Infrastructure\ITestRepository.cs" /> <Compile Include="Infrastructure\ITestRepository.cs" />
<Compile Include="Infrastructure\MongoDbDocumentTestBase.cs" />
<Compile Include="Infrastructure\MongoDbTKeyDocumentTestBase.cs" />
<Compile Include="Infrastructure\RandomExtensions.cs" />
<Compile Include="Infrastructure\TestClasses.cs" />
<Compile Include="Infrastructure\TestRepository.cs" /> <Compile Include="Infrastructure\TestRepository.cs" />
<Compile Include="CreateTests.cs" />
<Compile Include="ProjectPartitionedTKeyTests.cs" />
<Compile Include="ProjectPartitionedTests.cs" />
<Compile Include="ProjectTKeyTests.cs" />
<Compile Include="ProjectTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ReadPartitionedTKeyTests.cs" />
<Compile Include="ReadPartitionedTests.cs" />
<Compile Include="ReadTKeyTests.cs" />
<Compile Include="ReadTests.cs" />
<Compile Include="UpdatePartitionedTKeyTests.cs" />
<Compile Include="UpdatePartitionedTests.cs" />
<Compile Include="UpdateTKeyTests.cs" />
<Compile Include="UpdateTests.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="App.config"> <None Include="App.config">
@@ -88,11 +101,11 @@
<ItemGroup> <ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MongoDbGenericRepository\MongoDbGenericRepository.csproj">
<Project>{efc776c4-2af3-440c-be80-3fbe335817a5}</Project>
<Name>MongoDbGenericRepository</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.3.15.1\build\net35\NUnit3TestAdapter.props'))" />
</Target>
</Project> </Project>
@@ -1,143 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDB.Bson.Serialization.Attributes;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class ProjectTestsPartitionedTKeyDocument : IDocument<Guid>, IPartitionedDocument
{
[BsonId]
public Guid Id { get; set; }
public int Version { get; set; }
public ProjectTestsPartitionedTKeyDocument()
{
Id = Guid.NewGuid();
Version = 2;
PartitionKey = "TestPartitionKey";
Nested = new NestedTKey();
}
public string PartitionKey { get; set; }
public NestedTKey Nested { get; set; }
public string SomeContent { get; set; }
}
public class ProjectPartitionedTKeyTests : BaseMongoDbRepositoryTests<ProjectTestsPartitionedTKeyDocument>
{
[Test]
public async Task PartitionedProjectOneAsync()
{
// Arrange
const string someContent = "ProjectOneAsyncContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocument();
document.SomeContent = someContent;
document.Nested.SomeDate = someDate;
SUT.AddOne<ProjectTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = await SUT.ProjectOneAsync<ProjectTestsPartitionedTKeyDocument, MyProjection, Guid>(
x => x.Id == document.Id,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
},
PartitionKey);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(someContent, result.SomeContent);
Assert.AreEqual(someDate.Minute, result.SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.SomeDate.Second);
}
[Test]
public void PartitionedProjectOne()
{
// Arrange
const string someContent = "ProjectOneContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocument();
document.SomeContent = someContent;
document.Nested.SomeDate = someDate;
SUT.AddOne<ProjectTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = SUT.ProjectOne<ProjectTestsPartitionedTKeyDocument, MyProjection, Guid>(
x => x.Id == document.Id,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
},
PartitionKey);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(someContent, result.SomeContent);
Assert.AreEqual(someDate.Minute, result.SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.SomeDate.Second);
}
[Test]
public async Task PartitionedProjectManyAsync()
{
// Arrange
const string someContent = "ProjectManyAsyncContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocuments(5);
document.ForEach(e =>
{
e.SomeContent = someContent;
e.Nested.SomeDate = someDate;
});
SUT.AddMany<ProjectTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = await SUT.ProjectManyAsync<ProjectTestsPartitionedTKeyDocument, MyProjection, Guid>(
x => x.SomeContent == someContent,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
},
PartitionKey);
// Assert
Assert.AreEqual(5, result.Count);
Assert.AreEqual(someContent, result.First().SomeContent);
Assert.AreEqual(someDate.Minute, result.First().SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.First().SomeDate.Second);
}
[Test]
public void PartitionedProjectMany()
{
// Arrange
const string someContent = "ProjectManyContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocuments(5);
document.ForEach(e =>
{
e.SomeContent = someContent;
e.Nested.SomeDate = someDate;
});
SUT.AddMany<ProjectTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = SUT.ProjectMany<ProjectTestsPartitionedTKeyDocument, MyProjection, Guid>(
x => x.SomeContent == someContent,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
},
PartitionKey);
// Assert
Assert.AreEqual(5, result.Count);
Assert.AreEqual(someContent, result.First().SomeContent);
Assert.AreEqual(someDate.Minute, result.First().SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.First().SomeDate.Second);
}
}
}
-140
View File
@@ -1,140 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class ProjectTestsPartitionedDocument : PartitionedDocument
{
public ProjectTestsPartitionedDocument() : base("TestPartitionKey")
{
Version = 2;
Nested = new Nested
{
SomeDate = DateTime.UtcNow
};
}
public string SomeContent { get; set; }
public Nested Nested { get; set; }
}
public class ProjectPartitionedTests : BaseMongoDbRepositoryTests<ProjectTestsPartitionedDocument>
{
[Test]
public async Task PartitionedProjectOneAsync()
{
// Arrange
const string someContent = "ProjectOneAsyncContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocument();
document.SomeContent = someContent;
document.Nested.SomeDate = someDate;
SUT.AddOne(document);
// Act
var result = await SUT.ProjectOneAsync<ProjectTestsPartitionedDocument, MyProjection>(
x => x.Id == document.Id,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
},
PartitionKey);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(someContent, result.SomeContent);
Assert.AreEqual(someDate.Minute, result.SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.SomeDate.Second);
}
[Test]
public void PartitionedProjectOne()
{
// Arrange
const string someContent = "ProjectOneContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocument();
document.SomeContent = someContent;
document.Nested.SomeDate = someDate;
SUT.AddOne(document);
// Act
var result = SUT.ProjectOne<ProjectTestsPartitionedDocument, MyProjection>(
x => x.Id == document.Id,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
},
PartitionKey);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(someContent, result.SomeContent);
Assert.AreEqual(someDate.Minute, result.SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.SomeDate.Second);
}
[Test]
public async Task PartitionedProjectManyAsync()
{
// Arrange
const string someContent = "ProjectManyAsyncContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocuments(5);
document.ForEach(e =>
{
e.SomeContent = someContent;
e.Nested.SomeDate = someDate;
});
SUT.AddMany(document);
// Act
var result = await SUT.ProjectManyAsync<ProjectTestsPartitionedDocument, MyProjection>(
x => x.SomeContent == someContent,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
},
PartitionKey);
// Assert
Assert.AreEqual(5, result.Count);
Assert.AreEqual(someContent, result.First().SomeContent);
Assert.AreEqual(someDate.Minute, result.First().SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.First().SomeDate.Second);
}
[Test]
public void PartitionedProjectMany()
{
// Arrange
const string someContent = "ProjectManyContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocuments(5);
document.ForEach(e =>
{
e.SomeContent = someContent;
e.Nested.SomeDate = someDate;
});
SUT.AddMany(document);
// Act
var result = SUT.ProjectMany<ProjectTestsPartitionedDocument, MyProjection>(
x => x.SomeContent == someContent,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
},
PartitionKey);
// Assert
Assert.AreEqual(5, result.Count);
Assert.AreEqual(someContent, result.First().SomeContent);
Assert.AreEqual(someDate.Minute, result.First().SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.First().SomeDate.Second);
}
}
}
-150
View File
@@ -1,150 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDB.Bson.Serialization.Attributes;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class NestedTKey
{
public DateTime SomeDate { get; set; }
}
public class MyProjectionTKey
{
public DateTime SomeDate { get; set; }
public string SomeContent { get; set; }
}
public class ProjectTestsTKeyDocument : IDocument<Guid>
{
[BsonId]
public Guid Id { get; set; }
public int Version { get; set; }
public ProjectTestsTKeyDocument()
{
Id = Guid.NewGuid();
Version = 2;
Nested = new NestedTKey
{
SomeDate = DateTime.UtcNow
};
}
public string SomeContent { get; set; }
public NestedTKey Nested { get; set; }
}
public class ProjectTKeyTests : BaseMongoDbRepositoryTests<ProjectTestsTKeyDocument>
{
[Test]
public async Task ProjectOneAsync()
{
// Arrange
const string someContent = "ProjectOneAsyncContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocument();
document.SomeContent = someContent;
document.Nested.SomeDate = someDate;
SUT.AddOne<ProjectTestsTKeyDocument, Guid>(document);
// Act
var result = await SUT.ProjectOneAsync<ProjectTestsTKeyDocument, MyProjection, Guid>(
x => x.Id == document.Id,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
});
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(someContent, result.SomeContent);
Assert.AreEqual(someDate.Minute, result.SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.SomeDate.Second);
}
[Test]
public void ProjectOne()
{
// Arrange
const string someContent = "ProjectOneContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocument();
document.SomeContent = someContent;
document.Nested.SomeDate = someDate;
SUT.AddOne<ProjectTestsTKeyDocument, Guid>(document);
// Act
var result = SUT.ProjectOne<ProjectTestsTKeyDocument, MyProjection, Guid>(
x => x.Id == document.Id,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
});
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(someContent, result.SomeContent);
Assert.AreEqual(someDate.Minute, result.SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.SomeDate.Second);
}
[Test]
public async Task ProjectManyAsync()
{
// Arrange
const string someContent = "ProjectManyAsyncContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocuments(5);
document.ForEach(e =>
{
e.SomeContent = someContent;
e.Nested.SomeDate = someDate;
});
SUT.AddMany<ProjectTestsTKeyDocument, Guid>(document);
// Act
var result = await SUT.ProjectManyAsync<ProjectTestsTKeyDocument, MyProjection, Guid>(
x => x.SomeContent == someContent,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
});
// Assert
Assert.AreEqual(5, result.Count);
Assert.AreEqual(someContent, result.First().SomeContent);
Assert.AreEqual(someDate.Minute, result.First().SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.First().SomeDate.Second);
}
[Test]
public void ProjectMany()
{
// Arrange
const string someContent = "ProjectManyContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocuments(5);
document.ForEach(e =>
{
e.SomeContent = someContent;
e.Nested.SomeDate = someDate;
});
SUT.AddMany<ProjectTestsTKeyDocument, Guid>(document);
// Act
var result = SUT.ProjectMany<ProjectTestsTKeyDocument, MyProjection, Guid>(
x => x.SomeContent == someContent,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
});
// Assert
Assert.AreEqual(5, result.Count);
Assert.AreEqual(someContent, result.First().SomeContent);
Assert.AreEqual(someDate.Minute, result.First().SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.First().SomeDate.Second);
}
}
}
-149
View File
@@ -1,149 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class Nested
{
public DateTime SomeDate { get; set; }
}
public class MyProjection
{
public DateTime SomeDate { get; set; }
public string SomeContent { get; set; }
}
public class ProjectTestsDocument : Document
{
public ProjectTestsDocument()
{
Version = 2;
Nested = new Nested
{
SomeDate = DateTime.UtcNow
};
}
public string SomeContent { get; set; }
public Nested Nested { get; set; }
}
public class ProjectTests : BaseMongoDbRepositoryTests<ProjectTestsDocument>
{
[Test]
public async Task ProjectOneAsync()
{
// Arrange
const string someContent = "ProjectOneAsyncContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocument();
document.SomeContent = someContent;
document.Nested.SomeDate = someDate;
SUT.AddOne(document);
// Act
var result = await SUT.ProjectOneAsync<ProjectTestsDocument, MyProjection>(
x => x.Id == document.Id,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
});
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(someContent, result.SomeContent);
Assert.AreEqual(someDate.Minute, result.SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.SomeDate.Second);
}
[Test]
public void ProjectOne()
{
// Arrange
const string someContent = "ProjectOneContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocument();
document.SomeContent = someContent;
document.Nested.SomeDate = someDate;
SUT.AddOne(document);
// Act
var result = SUT.ProjectOne<ProjectTestsDocument, MyProjection>(
x => x.Id == document.Id,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
});
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(someContent, result.SomeContent);
Assert.AreEqual(someDate.Minute, result.SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.SomeDate.Second);
}
[Test]
public async Task ProjectManyAsync()
{
// Arrange
const string someContent = "ProjectManyAsyncContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocuments(5);
document.ForEach(e =>
{
e.SomeContent = someContent;
e.Nested.SomeDate = someDate;
});
SUT.AddMany(document);
// Act
var result = await SUT.ProjectManyAsync<ProjectTestsDocument, MyProjection>(
x => x.SomeContent == someContent,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
});
// Assert
Assert.AreEqual(5, result.Count);
Assert.AreEqual(someContent, result.First().SomeContent);
Assert.AreEqual(someDate.Minute, result.First().SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.First().SomeDate.Second);
}
[Test]
public void ProjectMany()
{
// Arrange
const string someContent = "ProjectManyContent";
var someDate = DateTime.UtcNow;
var document = CreateTestDocuments(5);
document.ForEach(e =>
{
e.SomeContent = someContent;
e.Nested.SomeDate = someDate;
});
SUT.AddMany(document);
// Act
var result = SUT.ProjectMany<ProjectTestsDocument, MyProjection>(
x => x.SomeContent == someContent,
x => new MyProjection
{
SomeContent = x.SomeContent,
SomeDate = x.Nested.SomeDate
});
// Assert
Assert.AreEqual(5, result.Count);
Assert.AreEqual(someContent, result.First().SomeContent);
Assert.AreEqual(someDate.Minute, result.First().SomeDate.Minute);
Assert.AreEqual(someDate.Second, result.First().SomeDate.Second);
}
}
}
@@ -1,189 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDB.Bson.Serialization.Attributes;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class ReadTestsPartitionedTKeyDocument : IDocument<Guid>, IPartitionedDocument
{
[BsonId]
public Guid Id { get; set; }
public int Version { get; set; }
public ReadTestsPartitionedTKeyDocument()
{
Id = Guid.NewGuid();
Version = 2;
PartitionKey = "TestPartitionKey";
}
public string PartitionKey { get; set; }
public string SomeContent { get; set; }
}
[TestFixture]
public class ReadPartitionedTKeyTests : BaseMongoDbRepositoryTests<ReadTestsPartitionedTKeyDocument>
{
[Test]
public async Task PartitionedGetByIdAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = await SUT.GetByIdAsync<ReadTestsPartitionedTKeyDocument, Guid>(document.Id, PartitionKey);
// Assert
Assert.IsNotNull(result);
}
[Test]
public void PartitionedGetById()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = SUT.GetById<ReadTestsPartitionedTKeyDocument, Guid>(document.Id, PartitionKey);
// Assert
Assert.IsNotNull(result);
}
[Test]
public async Task PartitionedGetOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = await SUT.GetOneAsync<ReadTestsPartitionedTKeyDocument, Guid>(x => x.Id == document.Id, PartitionKey);
// Assert
Assert.IsNotNull(result);
}
[Test]
public void PartitionedGetOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = SUT.GetOne<ReadTestsPartitionedTKeyDocument, Guid>(x => x.Id == document.Id, PartitionKey);
// Assert
Assert.IsNotNull(result);
}
[Test]
public void PartitionedGetCursor()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsPartitionedTKeyDocument, Guid>(document);
// Act
var cursor = SUT.GetCursor<ReadTestsPartitionedTKeyDocument, Guid>(x => x.Id == document.Id, PartitionKey);
var count = cursor.Count();
// Assert
Assert.AreEqual(1, count);
}
[Test]
public async Task PartitionedAnyAsyncReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = await SUT.AnyAsync<ReadTestsPartitionedTKeyDocument, Guid>(x => x.Id == document.Id, PartitionKey);
// Assert
Assert.AreEqual(true, result);
}
[Test]
public async Task PartitionedAnyAsyncReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = await SUT.AnyAsync<ReadTestsPartitionedTKeyDocument, Guid>(x => x.Id == Guid.NewGuid(), PartitionKey);
// Assert
Assert.AreEqual(false, result);
}
[Test]
public void PartitionedAnyReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = SUT.Any<ReadTestsPartitionedTKeyDocument, Guid>(x => x.Id == document.Id, PartitionKey);
// Assert
Assert.AreEqual(true, result);
}
[Test]
public void PartitionedAnyReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsPartitionedTKeyDocument, Guid>(document);
// Act
var result = SUT.Any<ReadTestsPartitionedTKeyDocument, Guid>(x => x.Id == Guid.NewGuid(), PartitionKey);
// Assert
Assert.AreEqual(false, result);
}
[Test]
public async Task PartitionedGetAllAsync()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "GetAllAsyncContent");
SUT.AddMany<ReadTestsPartitionedTKeyDocument, Guid>(documents);
// Act
var result = await SUT.GetAllAsync<ReadTestsPartitionedTKeyDocument, Guid>(x => x.SomeContent == "GetAllAsyncContent", PartitionKey);
// Assert
Assert.AreEqual(5, result.Count);
}
[Test]
public void PartitionedGetAll()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "GetAllContent");
SUT.AddMany<ReadTestsPartitionedTKeyDocument, Guid>(documents);
// Act
var result = SUT.GetAll<ReadTestsPartitionedTKeyDocument, Guid>(x => x.SomeContent == "GetAllContent", PartitionKey);
// Assert
Assert.AreEqual(5, result.Count);
}
[Test]
public async Task PartitionedCountAsync()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "CountAsyncContent");
SUT.AddMany<ReadTestsPartitionedTKeyDocument, Guid>(documents);
// Act
var result = await SUT.CountAsync<ReadTestsPartitionedTKeyDocument, Guid>(x => x.SomeContent == "CountAsyncContent", PartitionKey);
// Assert
Assert.AreEqual(5, result);
}
[Test]
public void PartitionedCount()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "CountContent");
SUT.AddMany<ReadTestsPartitionedTKeyDocument, Guid>(documents);
// Act
var result = SUT.Count<ReadTestsPartitionedTKeyDocument, Guid>(x => x.SomeContent == "CountContent", PartitionKey);
// Assert
Assert.AreEqual(5, result);
}
}
}
-181
View File
@@ -1,181 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class ReadTestsPartitionedDocument : PartitionedDocument
{
public ReadTestsPartitionedDocument() : base("TestPartitionKey")
{
Version = 1;
}
public string SomeContent { get; set; }
}
public class ReadPartitionedTests : BaseMongoDbRepositoryTests<ReadTestsPartitionedDocument>
{
[Test]
public async Task PartitionedGetByIdAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.GetByIdAsync<ReadTestsPartitionedDocument>(document.Id, PartitionKey);
// Assert
Assert.IsNotNull(result);
}
[Test]
public void PartitionedGetById()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.GetById<ReadTestsPartitionedDocument>(document.Id, PartitionKey);
// Assert
Assert.IsNotNull(result);
}
[Test]
public async Task PartitionedGetOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.GetOneAsync<ReadTestsPartitionedDocument>(x => x.Id == document.Id, PartitionKey);
// Assert
Assert.IsNotNull(result);
}
[Test]
public void PartitionedGetOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.GetOne<ReadTestsPartitionedDocument>(x => x.Id == document.Id, PartitionKey);
// Assert
Assert.IsNotNull(result);
}
[Test]
public void PartitionedGetCursor()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var cursor = SUT.GetCursor<ReadTestsPartitionedDocument>(x => x.Id == document.Id, PartitionKey);
var count = cursor.Count();
// Assert
Assert.AreEqual(1, count);
}
[Test]
public async Task PartitionedAnyAsyncReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.AnyAsync<ReadTestsPartitionedDocument>(x => x.Id == document.Id, PartitionKey);
// Assert
Assert.AreEqual(true, result);
}
[Test]
public async Task PartitionedAnyAsyncReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.AnyAsync<ReadTestsPartitionedDocument>(x => x.Id == Guid.NewGuid(), PartitionKey);
// Assert
Assert.AreEqual(false, result);
}
[Test]
public void PartitionedAnyReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.Any<ReadTestsPartitionedDocument>(x => x.Id == document.Id, PartitionKey);
// Assert
Assert.AreEqual(true, result);
}
[Test]
public void PartitionedAnyReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.Any<ReadTestsPartitionedDocument>(x => x.Id == Guid.NewGuid(), PartitionKey);
// Assert
Assert.AreEqual(false, result);
}
[Test]
public async Task PartitionedGetAllAsync()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "GetAllAsyncContent");
SUT.AddMany(documents);
// Act
var result = await SUT.GetAllAsync<ReadTestsPartitionedDocument>(x => x.SomeContent == "GetAllAsyncContent", PartitionKey);
// Assert
Assert.AreEqual(5, result.Count);
}
[Test]
public void PartitionedGetAll()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "GetAllContent");
SUT.AddMany(documents);
// Act
var result = SUT.GetAll<ReadTestsPartitionedDocument>(x => x.SomeContent == "GetAllContent", PartitionKey);
// Assert
Assert.AreEqual(5, result.Count);
}
[Test]
public async Task PartitionedCountAsync()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "CountAsyncContent");
SUT.AddMany(documents);
// Act
var result = await SUT.CountAsync<ReadTestsPartitionedDocument>(x => x.SomeContent == "CountAsyncContent", PartitionKey);
// Assert
Assert.AreEqual(5, result);
}
[Test]
public void PartitionedCount()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "CountContent");
SUT.AddMany(documents);
// Act
var result = SUT.Count<ReadTestsPartitionedDocument>(x => x.SomeContent == "CountContent", PartitionKey);
// Assert
Assert.AreEqual(5, result);
}
}
}
-187
View File
@@ -1,187 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDB.Bson.Serialization.Attributes;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class ReadTestsTKeyDocument : IDocument<Guid>
{
[BsonId]
public Guid Id { get; set; }
public int Version { get; set; }
public ReadTestsTKeyDocument()
{
Id = Guid.NewGuid();
Version = 2;
}
public string SomeContent { get; set; }
}
[TestFixture]
public class ReadTKeyTests : BaseMongoDbRepositoryTests<ReadTestsTKeyDocument>
{
[Test]
public async Task GetByIdAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsTKeyDocument, Guid>(document);
// Act
var result = await SUT.GetByIdAsync<ReadTestsTKeyDocument, Guid>(document.Id);
// Assert
Assert.IsNotNull(result);
}
[Test]
public void GetById()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsTKeyDocument, Guid>(document);
// Act
var result = SUT.GetById<ReadTestsTKeyDocument, Guid>(document.Id);
// Assert
Assert.IsNotNull(result);
}
[Test]
public async Task GetOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsTKeyDocument, Guid>(document);
// Act
var result = await SUT.GetOneAsync<ReadTestsTKeyDocument, Guid>(x => x.Id == document.Id);
// Assert
Assert.IsNotNull(result);
}
[Test]
public void GetOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsTKeyDocument, Guid>(document);
// Act
var result = SUT.GetOne<ReadTestsTKeyDocument, Guid>(x => x.Id == document.Id);
// Assert
Assert.IsNotNull(result);
}
[Test]
public void GetCursor()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsTKeyDocument, Guid>(document);
// Act
var cursor = SUT.GetCursor<ReadTestsTKeyDocument, Guid>(x => x.Id == document.Id);
var count = cursor.Count();
// Assert
Assert.AreEqual(1, count);
}
[Test]
public async Task AnyAsyncReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsTKeyDocument, Guid>(document);
// Act
var result = await SUT.AnyAsync<ReadTestsTKeyDocument, Guid>(x => x.Id == document.Id);
// Assert
Assert.AreEqual(true, result);
}
[Test]
public async Task AnyAsyncReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsTKeyDocument, Guid>(document);
// Act
var result = await SUT.AnyAsync<ReadTestsTKeyDocument, Guid>(x => x.Id == Guid.NewGuid());
// Assert
Assert.AreEqual(false, result);
}
[Test]
public void AnyReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsTKeyDocument, Guid>(document);
// Act
var result = SUT.Any<ReadTestsTKeyDocument, Guid>(x => x.Id == document.Id);
// Assert
Assert.AreEqual(true, result);
}
[Test]
public void AnyReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<ReadTestsTKeyDocument, Guid>(document);
// Act
var result = SUT.Any<ReadTestsTKeyDocument, Guid>(x => x.Id == Guid.NewGuid());
// Assert
Assert.AreEqual(false, result);
}
[Test]
public async Task GetAllAsync()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "GetAllAsyncContent");
SUT.AddMany<ReadTestsTKeyDocument, Guid>(documents);
// Act
var result = await SUT.GetAllAsync<ReadTestsTKeyDocument, Guid>(x => x.SomeContent == "GetAllAsyncContent");
// Assert
Assert.AreEqual(5, result.Count);
}
[Test]
public void GetAll()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "GetAllContent");
SUT.AddMany<ReadTestsTKeyDocument, Guid>(documents);
// Act
var result = SUT.GetAll<ReadTestsTKeyDocument, Guid>(x => x.SomeContent == "GetAllContent");
// Assert
Assert.AreEqual(5, result.Count);
}
[Test]
public async Task CountAsync()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "CountAsyncContent");
SUT.AddMany<ReadTestsTKeyDocument, Guid>(documents);
// Act
var result = await SUT.CountAsync<ReadTestsTKeyDocument, Guid>(x => x.SomeContent == "CountAsyncContent");
// Assert
Assert.AreEqual(5, result);
}
[Test]
public void Count()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "CountContent");
SUT.AddMany<ReadTestsTKeyDocument, Guid>(documents);
// Act
var result = SUT.Count<ReadTestsTKeyDocument, Guid>(x => x.SomeContent == "CountContent");
// Assert
Assert.AreEqual(5, result);
}
}
}
-182
View File
@@ -1,182 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class ReadTestsDocument : Document
{
public ReadTestsDocument()
{
Version = 2;
}
public string SomeContent { get; set; }
}
[TestFixture]
public class ReadTests : BaseMongoDbRepositoryTests<ReadTestsDocument>
{
[Test]
public async Task GetByIdAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.GetByIdAsync<ReadTestsDocument>(document.Id);
// Assert
Assert.IsNotNull(result);
}
[Test]
public void GetById()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.GetById<ReadTestsDocument>(document.Id);
// Assert
Assert.IsNotNull(result);
}
[Test]
public async Task GetOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.GetOneAsync<ReadTestsDocument>(x => x.Id == document.Id);
// Assert
Assert.IsNotNull(result);
}
[Test]
public void GetOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.GetOne<ReadTestsDocument>(x => x.Id == document.Id);
// Assert
Assert.IsNotNull(result);
}
[Test]
public void GetCursor()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var cursor = SUT.GetCursor<ReadTestsDocument>(x => x.Id == document.Id);
var count = cursor.Count();
// Assert
Assert.AreEqual(1, count);
}
[Test]
public async Task AnyAsyncReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.AnyAsync<ReadTestsDocument>(x => x.Id == document.Id);
// Assert
Assert.AreEqual(true, result);
}
[Test]
public async Task AnyAsyncReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = await SUT.AnyAsync<ReadTestsDocument>(x => x.Id == Guid.NewGuid());
// Assert
Assert.AreEqual(false, result);
}
[Test]
public void AnyReturnsTrue()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.Any<ReadTestsDocument>(x => x.Id == document.Id);
// Assert
Assert.AreEqual(true, result);
}
[Test]
public void AnyReturnsFalse()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
// Act
var result = SUT.Any<ReadTestsDocument>(x => x.Id == Guid.NewGuid());
// Assert
Assert.AreEqual(false, result);
}
[Test]
public async Task GetAllAsync()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "GetAllAsyncContent");
SUT.AddMany(documents);
// Act
var result = await SUT.GetAllAsync<ReadTestsDocument>(x => x.SomeContent == "GetAllAsyncContent");
// Assert
Assert.AreEqual(5, result.Count);
}
[Test]
public void GetAll()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "GetAllContent");
SUT.AddMany(documents);
// Act
var result = SUT.GetAll<ReadTestsDocument>(x => x.SomeContent == "GetAllContent");
// Assert
Assert.AreEqual(5, result.Count);
}
[Test]
public async Task CountAsync()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "CountAsyncContent");
SUT.AddMany(documents);
// Act
var result = await SUT.CountAsync<ReadTestsDocument>(x => x.SomeContent == "CountAsyncContent");
// Assert
Assert.AreEqual(5, result);
}
[Test]
public void Count()
{
// Arrange
var documents = CreateTestDocuments(5);
documents.ForEach(e => e.SomeContent = "CountContent");
SUT.AddMany(documents);
// Act
var result = SUT.Count<ReadTestsDocument>(x => x.SomeContent == "CountContent");
// Assert
Assert.AreEqual(5, result);
}
}
}
@@ -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<Guid>, IPartitionedDocument
{
[BsonId]
public Guid Id { get; set; }
public int Version { get; set; }
public UpdateTestsPartitionedTKeyDocument()
{
Id = Guid.NewGuid();
Version = 2;
PartitionKey = "TestPartitionKey";
Children = new List<Child>();
}
public string PartitionKey { get; set; }
public string SomeContent { get; set; }
public List<Child> Children { get; set; }
}
[TestFixture]
public class UpdatePartitionedTKeyTests : BaseMongoDbRepositoryTests<UpdateTestsPartitionedTKeyDocument>
{
[Test]
public void PartitionedUpdateOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<UpdateTestsPartitionedTKeyDocument, Guid>(document);
document.SomeContent = "UpdateOneContent";
// Act
var result = SUT.UpdateOne<UpdateTestsPartitionedTKeyDocument, Guid>(document);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsPartitionedTKeyDocument, Guid>(document.Id, PartitionKey);
Assert.IsNotNull(updatedDocument);
Assert.AreEqual("UpdateOneContent", updatedDocument.SomeContent);
}
[Test]
public async Task PartitionedUpdateOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<UpdateTestsPartitionedTKeyDocument, Guid>(document);
document.SomeContent = "UpdateOneAsyncContent";
// Act
var result = await SUT.UpdateOneAsync<UpdateTestsPartitionedTKeyDocument, Guid>(document);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsPartitionedTKeyDocument, Guid>(document.Id, PartitionKey);
Assert.IsNotNull(updatedDocument);
Assert.AreEqual("UpdateOneAsyncContent", updatedDocument.SomeContent);
}
[Test]
public async Task UpdateOneAsyncWithUpdateDefinition()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<UpdateTestsPartitionedTKeyDocument, Guid>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<UpdateTestsPartitionedTKeyDocument>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = await SUT.UpdateOneAsync<UpdateTestsPartitionedTKeyDocument, Guid>(document, updateDef);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsPartitionedTKeyDocument, Guid>(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<UpdateTestsPartitionedTKeyDocument, Guid>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<UpdateTestsPartitionedTKeyDocument>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = SUT.UpdateOne<UpdateTestsPartitionedTKeyDocument, Guid>(document, updateDef);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsPartitionedTKeyDocument, Guid>(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);
}
}
}
-205
View File
@@ -1,205 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDB.Driver;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class UpdateTestsPartitionedDocument : PartitionedDocument
{
public UpdateTestsPartitionedDocument() : base("TestPartitionKey")
{
Version = 2;
Children = new List<Child>();
}
public string SomeContent { get; set; }
public List<Child> Children { get; set; }
}
public class UpdatePartitionedTests : BaseMongoDbRepositoryTests<UpdateTestsPartitionedDocument>
{
[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<UpdateTestsPartitionedDocument>(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<UpdateTestsPartitionedDocument>(document.Id, PartitionKey);
Assert.IsNotNull(updatedDocument);
Assert.AreEqual("UpdateOneAsyncContent", updatedDocument.SomeContent);
}
[Test]
public async Task UpdateOneAsyncWithUpdateDefinition()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<UpdateTestsPartitionedDocument>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<UpdateTestsPartitionedDocument>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = await SUT.UpdateOneAsync<UpdateTestsPartitionedDocument>(document, updateDef);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsPartitionedDocument>(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<UpdateTestsPartitionedDocument>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<UpdateTestsPartitionedDocument>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = SUT.UpdateOne<UpdateTestsPartitionedDocument>(document, updateDef);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsPartitionedDocument>(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 UpdateOneWithFieldSelector()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
// Act
var result = SUT.UpdateOne(document, x => x.Children, childrenToAdd);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsPartitionedDocument>(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 async Task UpdateOneAsyncWithFieldSelector()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
// Act
var result = await SUT.UpdateOneAsync(document, x => x.Children, childrenToAdd);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsPartitionedDocument>(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 UpdateOneWithFilterAndFieldSelector()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
// Act
var filter = Builders<UpdateTestsPartitionedDocument>.Filter.Eq("Id", document.Id);
var result = SUT.UpdateOne(filter, x => x.Children, childrenToAdd, document.PartitionKey);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsPartitionedDocument>(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 async Task UpdateOneAsyncWithFilterAndFieldSelector()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
// Act
var filter = Builders<UpdateTestsPartitionedDocument>.Filter.Eq("Id", document.Id);
var result = await SUT.UpdateOneAsync(filter, x => x.Children, childrenToAdd, document.PartitionKey);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsPartitionedDocument>(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);
}
}
}
-195
View File
@@ -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<Guid>
{
[BsonId]
public Guid Id { get; set; }
public int Version { get; set; }
public UpdateTestsTKeyDocument()
{
Id = Guid.NewGuid();
Version = 2;
Children = new List<Child>();
}
public string SomeContent { get; set; }
public List<Child> Children { get; set; }
}
[TestFixture]
public class UpdateTKeyTests : BaseMongoDbRepositoryTests<UpdateTestsTKeyDocument>
{
[Test]
public void UpdateOne()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<UpdateTestsTKeyDocument, Guid>(document);
document.SomeContent = "UpdateOneContent";
// Act
var result = SUT.UpdateOne<UpdateTestsTKeyDocument, Guid>(document);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsTKeyDocument, Guid>(document.Id);
Assert.IsNotNull(updatedDocument);
Assert.AreEqual("UpdateOneContent", updatedDocument.SomeContent);
}
[Test]
public async Task UpdateOneAsync()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<UpdateTestsTKeyDocument, Guid>(document);
document.SomeContent = "UpdateOneAsyncContent";
// Act
var result = await SUT.UpdateOneAsync<UpdateTestsTKeyDocument, Guid>(document);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsTKeyDocument, Guid>(document.Id);
Assert.IsNotNull(updatedDocument);
Assert.AreEqual("UpdateOneAsyncContent", updatedDocument.SomeContent);
}
[Test]
public async Task UpdateOneAsyncWithUpdateDefinition()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne<UpdateTestsTKeyDocument, Guid>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<UpdateTestsTKeyDocument>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = await SUT.UpdateOneAsync<UpdateTestsTKeyDocument, Guid>(document, updateDef);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsTKeyDocument, Guid>(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<UpdateTestsTKeyDocument, Guid>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<UpdateTestsTKeyDocument>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = SUT.UpdateOne<UpdateTestsTKeyDocument, Guid>(document, updateDef);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsTKeyDocument, Guid>(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<UpdateTestsTKeyDocument, Guid>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var filter = Builders<UpdateTestsTKeyDocument>.Filter.Eq("Id", document.Id);
// Act
var result = SUT.UpdateOne<UpdateTestsTKeyDocument, Guid, List<Child>>(document, x => x.Children, childrenToAdd);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsTKeyDocument, Guid>(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<UpdateTestsTKeyDocument, Guid>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var filter = Builders<UpdateTestsTKeyDocument>.Filter.Eq("Id", document.Id);
// Act
var result = await SUT.UpdateOneAsync<UpdateTestsTKeyDocument, Guid, List<Child>>(document, x => x.Children, childrenToAdd);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsTKeyDocument, Guid>(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<UpdateTestsTKeyDocument, Guid>(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var filter = Builders<UpdateTestsTKeyDocument>.Filter.Eq("Id", document.Id);
// Act
var result = SUT.UpdateOne<UpdateTestsTKeyDocument, Guid, List<Child>>(filter, x => x.Children, childrenToAdd);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsTKeyDocument, Guid>(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);
}
}
}
-205
View File
@@ -1,205 +0,0 @@
using IntegrationTests.Infrastructure;
using MongoDB.Driver;
using MongoDbGenericRepository.Models;
using NUnit.Framework;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace IntegrationTests
{
public class UpdateTestsDocument : Document
{
public UpdateTestsDocument()
{
Version = 2;
Children = new List<Child>();
}
public string SomeContent { get; set; }
public List<Child> Children { get; set; }
}
public class UpdateTests : BaseMongoDbRepositoryTests<UpdateTestsDocument>
{
[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<UpdateTestsDocument>(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<UpdateTestsDocument>(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<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<UpdateTestsDocument>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = await SUT.UpdateOneAsync(document, updateDef);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsDocument>(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<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
var updateDef = Builders<UpdateTestsDocument>.Update.AddToSetEach(p => p.Children, childrenToAdd);
// Act
var result = SUT.UpdateOne(document, updateDef);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsDocument>(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<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
// Act
var result = SUT.UpdateOne(document, x => x.Children, childrenToAdd);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsDocument>(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<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
// Act
var result = await SUT.UpdateOneAsync(document, x => x.Children, childrenToAdd);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsDocument>(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<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
// Act
var filter = Builders<UpdateTestsDocument>.Filter.Eq("Id", document.Id);
var result = SUT.UpdateOne(filter, x => x.Children, childrenToAdd);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsDocument>(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 UpdateOneAsyncWithFilterAndFieldSelector()
{
// Arrange
var document = CreateTestDocument();
SUT.AddOne(document);
var childrenToAdd = new List<Child>
{
new Child("testType1", "testValue1"),
new Child("testType2", "testValue2")
};
// Act
var filter = Builders<UpdateTestsDocument>.Filter.Eq("Id", document.Id);
var result = await SUT.UpdateOneAsync(filter, x => x.Children, childrenToAdd);
// Assert
Assert.IsTrue(result);
var updatedDocument = SUT.GetById<UpdateTestsDocument>(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);
}
}
}
+12 -6
View File
@@ -1,10 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="MongoDB.Bson" version="2.4.4" targetFramework="net461" /> <package id="Crc32C.NET" version="1.0.5.0" targetFramework="net461" />
<package id="MongoDB.Driver" version="2.4.4" targetFramework="net461" /> <package id="DnsClient" version="1.2.0" targetFramework="net461" />
<package id="MongoDB.Driver.Core" version="2.4.4" targetFramework="net461" /> <package id="MongoDB.Bson" version="2.9.3" targetFramework="net461" />
<package id="NUnit" version="3.7.1" targetFramework="net461" /> <package id="MongoDB.Driver" version="2.9.3" targetFramework="net461" />
<package id="NUnit.ConsoleRunner" version="3.7.0" targetFramework="net461" /> <package id="MongoDB.Driver.Core" version="2.9.3" targetFramework="net461" />
<package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net461" /> <package id="MongoDbGenericRepository" version="1.4.5" targetFramework="net461" />
<package id="NUnit" version="3.12.0" targetFramework="net461" />
<package id="NUnit.ConsoleRunner" version="3.10.0" targetFramework="net461" />
<package id="NUnit3TestAdapter" version="3.15.1" targetFramework="net461" />
<package id="SharpCompress" version="0.23.0" targetFramework="net461" />
<package id="Snappy.NET" version="1.1.1.8" targetFramework="net461" />
<package id="System.Buffers" version="4.4.0" targetFramework="net461" />
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net461" /> <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net461" />
</packages> </packages>
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Alexandre SPIESER
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -1,5 +0,0 @@
<SolutionConfiguration>
<Settings>
<CurrentEngineMode>Run all tests automatically [Global]</CurrentEngineMode>
</Settings>
</SolutionConfiguration>
@@ -0,0 +1,69 @@
using MongoDB.Driver;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace MongoDbGenericRepository
{
/// <summary>
/// The IBaseMongoRepository interface exposes the CRUD functionality of the BaseMongoRepository.
/// </summary>
public interface IBaseMongoRepository :
IReadOnlyMongoRepository,
IBaseMongoRepository_Create,
IBaseMongoRepository_Update,
IBaseMongoRepository_Delete,
IBaseMongoRepository_Index
{
/// <summary>
/// Asynchronously returns a paginated list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter"></param>
/// <param name="skipNumber">The number of documents you want to skip. Default value is 0.</param>
/// <param name="takeNumber">The number of documents you want to take. Default value is 50.</param>
/// <param name="partitionKey">An optional partition key.</param>
Task<List<TDocument>> GetPaginatedAsync<TDocument>(Expression<Func<TDocument, bool>> filter, int skipNumber = 0, int takeNumber = 50, string partitionKey = null)
where TDocument : IDocument;
/// <summary>
/// Asynchronously returns a paginated list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter"></param>
/// <param name="skipNumber">The number of documents you want to skip. Default value is 0.</param>
/// <param name="takeNumber">The number of documents you want to take. Default value is 50.</param>
/// <param name="partitionKey">An optional partition key.</param>
Task<List<TDocument>> GetPaginatedAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, int skipNumber = 0, int takeNumber = 50, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// GetAndUpdateOne with filter
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter"></param>
/// <param name="update"></param>
/// <param name="options"></param>
/// <returns></returns>
Task<TDocument> GetAndUpdateOne<TDocument>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> update, FindOneAndUpdateOptions<TDocument, TDocument> options)
where TDocument : IDocument;
/// <summary>
/// GetAndUpdateOne with filter
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter"></param>
/// <param name="update"></param>
/// <param name="options"></param>
/// <returns></returns>
Task<TDocument> GetAndUpdateOne<TDocument, TKey>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> update, FindOneAndUpdateOptions<TDocument, TDocument> options)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
}
}
@@ -0,0 +1,242 @@
using MongoDB.Driver;
using MongoDbGenericRepository.Models;
using System;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace MongoDbGenericRepository
{
/// <summary>
/// The IBaseMongoRepository_Update interface exposing update functionality for documents with Guid Ids.
/// </summary>
public interface IBaseMongoRepository_Update : IBaseMongoRepository_Update<Guid>
{
/// <summary>
/// Asynchronously Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
Task<bool> UpdateOneAsync<TDocument, TKey>(TDocument modifiedDocument)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
bool UpdateOne<TDocument, TKey>(TDocument modifiedDocument)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Takes a document you want to modify and applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="update">The update definition for the document.</param>
Task<bool> UpdateOneAsync<TDocument, TKey>(TDocument documentToModify, UpdateDefinition<TDocument> update)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Takes a document you want to modify and applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="update">The update definition for the document.</param>
bool UpdateOne<TDocument, TKey>(TDocument documentToModify, UpdateDefinition<TDocument> update)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// For the entity selected by the filter, updates the property field with the given value..
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
bool UpdateOne<TDocument, TKey, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
Task<bool> UpdateOneAsync<TDocument, TKey, TField>(TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// For the entity selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
Task<bool> UpdateOneAsync<TDocument, TKey, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
bool UpdateOne<TDocument, TKey, TField>(TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
Task<bool> UpdateOneAsync<TDocument, TKey, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
bool UpdateOne<TDocument, TKey, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
Task<long> UpdateManyAsync<TDocument, TKey, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
Task<long> UpdateManyAsync<TDocument, TKey, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
Task<long> UpdateManyAsync<TDocument, TKey>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
Task<long> UpdateManyAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
long UpdateMany<TDocument, TKey, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
long UpdateMany<TDocument, TKey, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
long UpdateMany<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
long UpdateMany<TDocument, TKey>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
}
}
@@ -0,0 +1,169 @@
using System;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDbGenericRepository.Models;
namespace MongoDbGenericRepository.DataAccess.Update
{
/// <summary>
/// The IBaseMongoRepository_Update_ClientSession interface exposing update functionality with a IClientSessionHandle.
/// </summary>
public interface IBaseMongoRepository_Update_ClientSession
{
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="filter">The filter for the update.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="partitionKey">The optional partition key.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
bool UpdateOne<TDocument, TKey, TField>(IClientSessionHandle session, Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="filter">The filter for the update.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="partitionKey">The optional partition key.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
bool UpdateOne<TDocument, TKey, TField>(IClientSessionHandle session, FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="documentToModify">The document to modify.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
bool UpdateOne<TDocument, TKey, TField>(IClientSessionHandle session, TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
bool UpdateOne<TDocument, TKey>(IClientSessionHandle session, TDocument modifiedDocument, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="documentToModify">The document to modify.</param>
/// <param name="update">The update definition.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
bool UpdateOne<TDocument, TKey>(IClientSessionHandle session, TDocument documentToModify, UpdateDefinition<TDocument> update, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="filter">The filter for the update.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="partitionKey">The optional partition key.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
Task<bool> UpdateOneAsync<TDocument, TKey, TField>(IClientSessionHandle session, Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="filter">The filter for the update.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="partitionKey">The optional partition key.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns></returns>
Task<bool> UpdateOneAsync<TDocument, TKey, TField>(IClientSessionHandle session, FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="documentToModify">The document to modify.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
Task<bool> UpdateOneAsync<TDocument, TKey, TField>(IClientSessionHandle session, TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
Task<bool> UpdateOneAsync<TDocument, TKey>(IClientSessionHandle session, TDocument modifiedDocument, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="documentToModify">The document to modify.</param>
/// <param name="update">The update definition.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
Task<bool> UpdateOneAsync<TDocument, TKey>(IClientSessionHandle session, TDocument documentToModify, UpdateDefinition<TDocument> update, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
}
}
@@ -0,0 +1,502 @@
using MongoDB.Driver;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
namespace MongoDbGenericRepository
{
/// <summary>
/// The IBaseReadOnlyRepository exposes the generic Read Only functionality of the BaseMongoRepository.
/// </summary>
public interface IBaseReadOnlyRepository
{
/// <summary>
/// The connection string.
/// </summary>
string ConnectionString { get; }
/// <summary>
/// The database name.
/// </summary>
string DatabaseName { get; }
#region Read TKey
/// <summary>
/// Asynchronously returns one document given its id.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="id">The Id of the document you want to get.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task<TDocument> GetByIdAsync<TDocument, TKey>(TKey id, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Returns one document given its id.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="id">The Id of the document you want to get.</param>
/// <param name="partitionKey">An optional partition key.</param>
TDocument GetById<TDocument, TKey>(TKey id, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Asynchronously returns one document given an expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task<TDocument> GetOneAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Returns one document given an expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
TDocument GetOne<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Returns a collection cursor.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
IFindFluent<TDocument, TDocument> GetCursor<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Returns true if any of the document of the collection matches the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task<bool> AnyAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Returns true if any of the document of the collection matches the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
bool Any<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Asynchronously returns a list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task<List<TDocument>> GetAllAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Returns a list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
List<TDocument> GetAll<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Asynchronously counts how many documents match the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partitionKey</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task<long> CountAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Counts how many documents match the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partitionKey</param>
long Count<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
#endregion
#region Min / Max
/// <summary>
/// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="maxValueSelector">A property selector to order by descending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task<TDocument> GetByMaxAsync<TDocument, TKey>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, object>> maxValueSelector,
string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="orderByDescending">A property selector to order by descending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
TDocument GetByMax<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, object>> orderByDescending, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Gets the document with the minimum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector for the minimum value you are looking for.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task<TDocument> GetByMinAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, object>> minValueSelector,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Gets the document with the minimum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector for the minimum value you are looking for.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
TDocument GetByMin<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, object>> minValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Gets the maximum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="maxValueSelector">A property selector for the maximum value you are looking for.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task<TValue> GetMaxValueAsync<TDocument, TKey, TValue>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, TValue>> maxValueSelector,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Gets the maximum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="maxValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
TValue GetMaxValue<TDocument, TKey, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> maxValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Gets the minimum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task<TValue> GetMinValueAsync<TDocument, TKey, TValue>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, TValue>> minValueSelector,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Gets the minimum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partition key.</param>
TValue GetMinValue<TDocument, TKey, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
#endregion
#region Sum
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task<int> SumByAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, int>> selector,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
int SumBy<TDocument, TKey>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, int>> selector,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
Task<decimal> SumByAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, decimal>> selector,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
decimal SumBy<TDocument, TKey>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, decimal>> selector,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
#endregion Sum
#region Project TKey
/// <summary>
/// Asynchronously returns a projected document matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task<TProjection> ProjectOneAsync<TDocument, TProjection, TKey>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, TProjection>> projection,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
where TProjection : class;
/// <summary>
/// Returns a projected document matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter"></param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
TProjection ProjectOne<TDocument, TProjection, TKey>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
where TProjection : class;
/// <summary>
/// Asynchronously returns a list of projected documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task<List<TProjection>> ProjectManyAsync<TDocument, TProjection, TKey>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, TProjection>> projection,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
where TProjection : class;
/// <summary>
/// Asynchronously returns a list of projected documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter"></param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
List<TProjection> ProjectMany<TDocument, TProjection, TKey>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
where TProjection : class;
#endregion
#region Group By
/// <summary>
/// Groups filtered a collection of documents given a grouping criteria,
/// and returns a dictionary of listed document groups with keys having the different values of the grouping criteria.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TGroupKey">The type of the grouping criteria.</typeparam>
/// <typeparam name="TProjection">The type of the projected group.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="groupingCriteria">The grouping criteria.</param>
/// <param name="groupProjection">The projected group result.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
List<TProjection> GroupBy<TDocument, TGroupKey, TProjection, TKey>(
Expression<Func<TDocument, TGroupKey>> groupingCriteria,
Expression<Func<IGrouping<TGroupKey, TDocument>, TProjection>> groupProjection,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
where TProjection : class, new();
/// <summary>
/// Groups filtered a collection of documents given a grouping criteria,
/// and returns a dictionary of listed document groups with keys having the different values of the grouping criteria.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TGroupKey">The type of the grouping criteria.</typeparam>
/// <typeparam name="TProjection">The type of the projected group.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="groupingCriteria">The grouping criteria.</param>
/// <param name="groupProjection">The projected group result.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
List<TProjection> GroupBy<TDocument, TGroupKey, TProjection, TKey>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, TGroupKey>> groupingCriteria,
Expression<Func<IGrouping<TGroupKey, TDocument>, TProjection>> groupProjection,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
where TProjection : class, new();
#endregion Group By
#region Pagination
/// <summary>
/// Asynchronously returns a paginated list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="sortSelector">The property selector.</param>
/// <param name="ascending">Order of the sorting.</param>
/// <param name="skipNumber">The number of documents you want to skip. Default value is 0.</param>
/// <param name="takeNumber">The number of documents you want to take. Default value is 50.</param>
/// <param name="partitionKey">An optional partition key.</param>
Task<List<TDocument>> GetSortedPaginatedAsync<TDocument, TKey>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, object>> sortSelector,
bool ascending = true,
int skipNumber = 0,
int takeNumber = 50,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Asynchronously returns a paginated list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="sortDefinition">The sort definition.</param>
/// <param name="skipNumber">The number of documents you want to skip. Default value is 0.</param>
/// <param name="takeNumber">The number of documents you want to take. Default value is 50.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task<List<TDocument>> GetSortedPaginatedAsync<TDocument, TKey>(
Expression<Func<TDocument, bool>> filter,
SortDefinition<TDocument> sortDefinition,
int skipNumber = 0,
int takeNumber = 50,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
#endregion Pagination
}
}
@@ -19,39 +19,23 @@ namespace MongoDbGenericRepository
/// </summary> /// </summary>
IMongoDatabase Database { get; } IMongoDatabase Database { get; }
/// <summary>
/// The private GetCollection method
/// </summary>
/// <typeparam name="TDocument"></typeparam>
IMongoCollection<TDocument> GetCollection<TDocument>();
/// <summary> /// <summary>
/// Returns a collection for a document type that has a partition key. /// Returns a collection for a document type that has a partition key.
/// </summary> /// </summary>
/// <typeparam name="TDocument"></typeparam> /// <typeparam name="TDocument"></typeparam>
/// <param name="partitionKey">The value of the partition key.</param> /// <param name="partitionKey">The value of the partition key.</param>
IMongoCollection<TDocument> GetCollection<TDocument>(string partitionKey) where TDocument : IDocument; IMongoCollection<TDocument> GetCollection<TDocument>(string partitionKey = null);
/// <summary>
/// Returns a collection for a document type that has a partition key.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="partitionKey">The value of the partition key.</param>
IMongoCollection<TDocument> GetCollection<TDocument, TKey>(string partitionKey)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Drops a collection, use very carefully.
/// </summary>
/// <typeparam name="TDocument"></typeparam>
void DropCollection<TDocument>();
/// <summary> /// <summary>
/// Drops a collection having a partitionkey, use very carefully. /// Drops a collection having a partitionkey, use very carefully.
/// </summary> /// </summary>
/// <typeparam name="TDocument"></typeparam> /// <typeparam name="TDocument"></typeparam>
void DropCollection<TDocument>(string partitionKey); void DropCollection<TDocument>(string partitionKey = null);
/// <summary>
/// Sets the Guid representation of the MongoDb Driver.
/// </summary>
/// <param name="guidRepresentation">The new value of the GuidRepresentation</param>
void SetGuidRepresentation(MongoDB.Bson.GuidRepresentation guidRepresentation);
} }
} }
@@ -0,0 +1,381 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDbGenericRepository.Models;
namespace MongoDbGenericRepository
{
public interface IReadOnlyMongoRepository<TKey> where TKey : IEquatable<TKey>
{
#region Read
/// <summary>
/// Asynchronously returns one document given its id.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="id">The Id of the document you want to get.</param>
/// <param name="partitionKey">An optional partition key.</param>
Task<TDocument> GetByIdAsync<TDocument>(TKey id, string partitionKey = null) where TDocument : IDocument<TKey>;
/// <summary>
/// Returns one document given its id.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="id">The Id of the document you want to get.</param>
/// <param name="partitionKey">An optional partition key.</param>
TDocument GetById<TDocument>(TKey id, string partitionKey = null) where TDocument : IDocument<TKey>;
/// <summary>
/// Asynchronously returns one document given an expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
Task<TDocument> GetOneAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>;
/// <summary>
/// Returns one document given an expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
TDocument GetOne<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>;
/// <summary>
/// Returns a collection cursor.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
IFindFluent<TDocument, TDocument> GetCursor<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>;
/// <summary>
/// Asynchronously returns true if any of the document of the collection matches the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
Task<bool> AnyAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>;
/// <summary>
/// Returns true if any of the document of the collection matches the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
bool Any<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>;
/// <summary>
/// Asynchronously returns a list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
Task<List<TDocument>> GetAllAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>;
/// <summary>
/// Returns a list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
List<TDocument> GetAll<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>;
/// <summary>
/// Asynchronously counts how many documents match the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
Task<long> CountAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>;
/// <summary>
/// Counts how many documents match the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
long Count<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>;
#endregion
#region Min / Max
/// <summary>
/// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="orderByDescending">A property selector to order by descending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
Task<TDocument> GetByMaxAsync<TDocument>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, object>> orderByDescending, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="orderByDescending">A property selector to order by descending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
/// <returns></returns>
TDocument GetByMax<TDocument>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, object>> orderByDescending, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="orderByAscending">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
Task<TDocument> GetByMinAsync<TDocument>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, object>> orderByAscending, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="orderByAscending">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
TDocument GetByMin<TDocument>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, object>> orderByAscending, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Gets the maximum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="maxValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
Task<TValue> GetMaxValueAsync<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> maxValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Gets the maximum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="maxValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
TValue GetMaxValue<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> maxValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Gets the minimum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partition key.</param>
Task<TValue> GetMinValueAsync<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Gets the minimum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partition key.</param>
TValue GetMinValue<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>;
#endregion
#region Maths
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
Task<int> SumByAsync<TDocument>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, int>> selector,
string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
Task<decimal> SumByAsync<TDocument>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, decimal>> selector,
string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
int SumBy<TDocument>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, int>> selector,
string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
decimal SumBy<TDocument>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, decimal>> selector,
string partitionKey = null)
where TDocument : IDocument<TKey>;
#endregion Maths
#region Project
/// <summary>
/// Asynchronously returns a projected document matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
Task<TProjection> ProjectOneAsync<TDocument, TProjection>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
where TDocument : IDocument<TKey>
where TProjection : class;
/// <summary>
/// Returns a projected document matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
TProjection ProjectOne<TDocument, TProjection>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
where TDocument : IDocument<TKey>
where TProjection : class;
/// <summary>
/// Asynchronously returns a list of projected documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
Task<List<TProjection>> ProjectManyAsync<TDocument, TProjection>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
where TDocument : IDocument<TKey>
where TProjection : class;
/// <summary>
/// Asynchronously returns a list of projected documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
List<TProjection> ProjectMany<TDocument, TProjection>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
where TDocument : IDocument<TKey>
where TProjection : class;
#endregion Project
#region Group By
/// <summary>
/// Groups a collection of documents given a grouping criteria,
/// and returns a dictionary of listed document groups with keys having the different values of the grouping criteria.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TGroupKey">The type of the grouping criteria.</typeparam>
/// <typeparam name="TProjection">The type of the projected group.</typeparam>
/// <param name="groupingCriteria">The grouping criteria.</param>
/// <param name="groupProjection">The projected group result.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
List<TProjection> GroupBy<TDocument, TGroupKey, TProjection>(
Expression<Func<TDocument, TGroupKey>> groupingCriteria,
Expression<Func<IGrouping<TGroupKey, TDocument>, TProjection>> groupProjection,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TProjection : class, new();
/// <summary>
/// Groups filtered a collection of documents given a grouping criteria,
/// and returns a dictionary of listed document groups with keys having the different values of the grouping criteria.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TGroupKey">The type of the grouping criteria.</typeparam>
/// <typeparam name="TProjection">The type of the projected group.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="groupingCriteria">The grouping criteria.</param>
/// <param name="groupProjection">The projected group result.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
List<TProjection> GroupBy<TDocument, TGroupKey, TProjection>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, TGroupKey>> groupingCriteria,
Expression<Func<IGrouping<TGroupKey, TDocument>, TProjection>> groupProjection,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TProjection : class, new();
#endregion Group By
#region Pagination
/// <summary>
/// Asynchronously returns a paginated list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="sortSelector">The property selector.</param>
/// <param name="ascending">Order of the sorting.</param>
/// <param name="skipNumber">The number of documents you want to skip. Default value is 0.</param>
/// <param name="takeNumber">The number of documents you want to take. Default value is 50.</param>
/// <param name="partitionKey">An optional partition key.</param>
Task<List<TDocument>> GetSortedPaginatedAsync<TDocument>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, object>> sortSelector,
bool ascending = true,
int skipNumber = 0,
int takeNumber = 50,
string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Asynchronously returns a paginated list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="sortDefinition">The sort definition.</param>
/// <param name="skipNumber">The number of documents you want to skip. Default value is 0.</param>
/// <param name="takeNumber">The number of documents you want to take. Default value is 50.</param>
/// <param name="partitionKey">An optional partition key.</param>
Task<List<TDocument>> GetSortedPaginatedAsync<TDocument>(
Expression<Func<TDocument, bool>> filter,
SortDefinition<TDocument> sortDefinition,
int skipNumber = 0,
int takeNumber = 50,
string partitionKey = null)
where TDocument : IDocument<TKey>;
#endregion Pagination
}
}
@@ -0,0 +1,12 @@
using System;
namespace MongoDbGenericRepository
{
/// <summary>
/// The IReadOnlyMongoRepository exposes the readonly functionality of the BaseMongoRepository.
/// </summary>
public interface IReadOnlyMongoRepository : IBaseReadOnlyRepository, IReadOnlyMongoRepository<Guid>
{
}
}
@@ -0,0 +1,29 @@
using System;
namespace MongoDbGenericRepository.Attributes
{
/// <summary>
/// This attribute allows you to specify of the name of the collection.
/// Added at commit c117bf2a7fee378f1e02199dea9b2023a7089ee2 by https://github.com/Etchelon
/// who has included the CollectionName attribute into the repo to give another choice to the user on how
/// to name their collections.
/// The attribute takes precedence of course, and if not present the library will fall back to your Pluralize method.
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class CollectionNameAttribute : Attribute
{
/// <summary>
/// The name of the collection in which your documents are stored.
/// </summary>
public string Name { get; set; }
/// <summary>
/// The constructor.
/// </summary>
/// <param name="name">The name of the collection.</param>
public CollectionNameAttribute(string name)
{
this.Name = name;
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,202 @@
using MongoDbGenericRepository.DataAccess.Create;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace MongoDbGenericRepository
{
/// <summary>
/// The IBaseMongoRepository_Create interface to expose document creation functionality
/// with document having an Id of type Guid.
/// </summary>
public interface IBaseMongoRepository_Create : IBaseMongoRepository_Create<Guid>
{
/// <summary>
/// Asynchronously adds a document to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="document">The document you want to add.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task AddOneAsync<TDocument, TKey>(TDocument document, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Adds a document to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="document">The document you want to add.</param>
void AddOne<TDocument, TKey>(TDocument document)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Asynchronously adds a list of documents to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documents">The documents you want to add.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task AddManyAsync<TDocument, TKey>(IEnumerable<TDocument> documents, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Adds a list of documents to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documents">The documents you want to add.</param>
void AddMany<TDocument, TKey>(IEnumerable<TDocument> documents)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
}
/// <summary>
/// The base Repository, it is meant to be inherited from by your custom custom MongoRepository implementation.
/// Its constructor must be given a connection string and a database name.
/// </summary>
public abstract partial class BaseMongoRepository : IBaseMongoRepository_Create
{
private readonly object _initLock = new object();
private MongoDbCreator _mongoDbCreator;
/// <summary>
/// The MongoDbCreator field.
/// </summary>
protected virtual MongoDbCreator MongoDbCreator
{
get
{
if (_mongoDbCreator != null) { return _mongoDbCreator; }
lock (_initLock)
{
if (_mongoDbCreator == null)
{
_mongoDbCreator = new MongoDbCreator(MongoDbContext);
}
}
return _mongoDbCreator;
}
set { _mongoDbCreator = value; }
}
/// <summary>
/// Asynchronously adds a document to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="document">The document you want to add.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task AddOneAsync<TDocument, TKey>(TDocument document, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
await MongoDbCreator.AddOneAsync<TDocument, TKey>(document, cancellationToken);
}
/// <summary>
/// Asynchronously adds a document to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="document">The document you want to add.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task AddOneAsync<TDocument>(TDocument document, CancellationToken cancellationToken = default)
where TDocument : IDocument<Guid>
{
await MongoDbCreator.AddOneAsync<TDocument, Guid>(document, cancellationToken);
}
/// <summary>
/// Adds a document to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="document">The document you want to add.</param>
public virtual void AddOne<TDocument, TKey>(TDocument document)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
MongoDbCreator.AddOne<TDocument, TKey>(document);
}
/// <summary>
/// Adds a document to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="document">The document you want to add.</param>
public virtual void AddOne<TDocument>(TDocument document) where TDocument : IDocument<Guid>
{
MongoDbCreator.AddOne<TDocument, Guid>(document);
}
/// <summary>
/// Asynchronously adds a list of documents to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documents">The documents you want to add.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task AddManyAsync<TDocument, TKey>(IEnumerable<TDocument> documents, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
await MongoDbCreator.AddManyAsync<TDocument, TKey>(documents, cancellationToken);
}
/// <summary>
/// Asynchronously adds a list of documents to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documents">The documents you want to add.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task AddManyAsync<TDocument>(IEnumerable<TDocument> documents, CancellationToken cancellationToken = default)
where TDocument : IDocument<Guid>
{
await MongoDbCreator.AddManyAsync<TDocument, Guid>(documents, cancellationToken);
}
/// <summary>
/// Adds a list of documents to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documents">The documents you want to add.</param>
public virtual void AddMany<TDocument, TKey>(IEnumerable<TDocument> documents)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
MongoDbCreator.AddMany<TDocument, TKey>(documents);
}
/// <summary>
/// Adds a list of documents to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documents">The documents you want to add.</param>
public virtual void AddMany<TDocument>(IEnumerable<TDocument> documents)
where TDocument : IDocument<Guid>
{
MongoDbCreator.AddMany<TDocument, Guid>(documents);
}
}
}
@@ -0,0 +1,344 @@
using MongoDbGenericRepository.DataAccess.Delete;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace MongoDbGenericRepository
{
public interface IBaseMongoRepository_Delete : IBaseMongoRepository_Delete<Guid>
{
/// <summary>
/// Deletes a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="document">The document you want to delete.</param>
/// <returns>The number of documents deleted.</returns>
long DeleteOne<TDocument, TKey>(TDocument document)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Asynchronously deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="document">The document you want to delete.</param>
/// <returns>The number of documents deleted.</returns>
Task<long> DeleteOneAsync<TDocument, TKey>(TDocument document)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
long DeleteOne<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Asynchronously deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
Task<long> DeleteOneAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Asynchronously deletes the documents matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
Task<long> DeleteManyAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Asynchronously deletes a list of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documents">The list of documents to delete.</param>
/// <returns>The number of documents deleted.</returns>
Task<long> DeleteManyAsync<TDocument, TKey>(IEnumerable<TDocument> documents)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Deletes a list of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documents">The list of documents to delete.</param>
/// <returns>The number of documents deleted.</returns>
long DeleteMany<TDocument, TKey>(IEnumerable<TDocument> documents)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Deletes the documents matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
long DeleteMany<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
}
public abstract partial class BaseMongoRepository : IBaseMongoRepository_Delete
{
private MongoDbEraser _mongoDbEraser;
protected virtual MongoDbEraser MongoDbEraser
{
get
{
if (_mongoDbEraser != null) { return _mongoDbEraser; }
lock (_initLock)
{
if (_mongoDbEraser == null)
{
_mongoDbEraser = new MongoDbEraser(MongoDbContext);
}
}
return _mongoDbEraser;
}
set { _mongoDbEraser = value; }
}
#region Delete
/// <summary>
/// Asynchronously deletes a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="document">The document you want to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteOneAsync<TDocument>(TDocument document) where TDocument : IDocument<Guid>
{
return await MongoDbEraser.DeleteOneAsync<TDocument, Guid>(document);
}
/// <summary>
/// Deletes a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="document">The document you want to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteOne<TDocument>(TDocument document) where TDocument : IDocument<Guid>
{
return MongoDbEraser.DeleteOne<TDocument, Guid>(document);
}
/// <summary>
/// Deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteOne<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<Guid>
{
return MongoDbEraser.DeleteOne<TDocument, Guid>(filter, partitionKey);
}
/// <summary>
/// Asynchronously deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteOneAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<Guid>
{
return await MongoDbEraser.DeleteOneAsync<TDocument, Guid>(filter, partitionKey);
}
/// <summary>
/// Asynchronously deletes the documents matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteManyAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<Guid>
{
return await MongoDbEraser.DeleteManyAsync<TDocument, Guid>(filter, partitionKey);
}
/// <summary>
/// Asynchronously deletes a list of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documents">The list of documents to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteManyAsync<TDocument>(IEnumerable<TDocument> documents) where TDocument : IDocument<Guid>
{
return await DeleteManyAsync<TDocument, Guid>(documents);
}
/// <summary>
/// Deletes a list of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documents">The list of documents to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteMany<TDocument>(IEnumerable<TDocument> documents) where TDocument : IDocument<Guid>
{
return DeleteMany<TDocument, Guid>(documents);
}
/// <summary>
/// Deletes the documents matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteMany<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<Guid>
{
return MongoDbEraser.DeleteMany<TDocument, Guid>(filter, partitionKey);
}
#endregion Delete
#region Delete TKey
/// <summary>
/// Deletes a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="document">The document you want to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteOne<TDocument, TKey>(TDocument document)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbEraser.DeleteOne<TDocument, TKey>(document);
}
/// <summary>
/// Asynchronously deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="document">The document you want to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteOneAsync<TDocument, TKey>(TDocument document)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbEraser.DeleteOneAsync<TDocument, TKey>(document);
}
/// <summary>
/// Deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteOne<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbEraser.DeleteOne<TDocument, TKey>(filter, partitionKey);
}
/// <summary>
/// Asynchronously deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteOneAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbEraser.DeleteOneAsync<TDocument, TKey>(filter, partitionKey);
}
/// <summary>
/// Asynchronously deletes the documents matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteManyAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbEraser.DeleteManyAsync<TDocument, TKey>(filter, partitionKey);
}
/// <summary>
/// Asynchronously deletes a list of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documents">The list of documents to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteManyAsync<TDocument, TKey>(IEnumerable<TDocument> documents)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbEraser.DeleteManyAsync<TDocument, TKey>(documents);
}
/// <summary>
/// Deletes a list of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documents">The list of documents to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteMany<TDocument, TKey>(IEnumerable<TDocument> documents)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbEraser.DeleteMany<TDocument, TKey>(documents);
}
/// <summary>
/// Deletes the documents matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteMany<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbEraser.DeleteMany<TDocument, TKey>(filter, partitionKey);
}
#endregion
}
}
@@ -0,0 +1,320 @@
using MongoDbGenericRepository.DataAccess.Index;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq.Expressions;
using MongoDbGenericRepository.Models;
namespace MongoDbGenericRepository
{
public interface IBaseMongoRepository_Index : IBaseMongoRepository_Index<Guid>
{
/// <summary>
/// Returns the names of the indexes present on a collection.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="partitionKey">An optional partition key</param>
/// <returns>A list containing the names of the indexes on on the concerned collection.</returns>
Task<List<string>> GetIndexesNamesAsync<TDocument, TKey>(string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Create a text index on the given field.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
Task<string> CreateTextIndexAsync<TDocument, TKey>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Creates an index on the given field in ascending order.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
Task<string> CreateAscendingIndexAsync<TDocument, TKey>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Creates an index on the given field in descending order.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
Task<string> CreateDescendingIndexAsync<TDocument, TKey>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Creates a hashed index on the given field.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
Task<string> CreateHashedIndexAsync<TDocument, TKey>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Creates a combined text index.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="fields">The fields we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
Task<string> CreateCombinedTextIndexAsync<TDocument, TKey>(IEnumerable<Expression<Func<TDocument, object>>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
/// <summary>
/// Drops the index given a field name
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="indexName">The name of the index</param>
/// <param name="partitionKey">An optional partition key</param>
Task DropIndexAsync<TDocument, TKey>(string indexName, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>;
}
/// <summary>
/// The base Repository, it is meant to be inherited from by your custom custom MongoRepository implementation.
/// Its constructor must be given a connection string and a database name.
/// </summary>
public abstract partial class BaseMongoRepository : IBaseMongoRepository_Index
{
private MongoDbIndexHandler _mongoDbIndexHandler;
protected virtual MongoDbIndexHandler MongoDbIndexHandler
{
get
{
if (_mongoDbIndexHandler != null) { return _mongoDbIndexHandler; }
lock (_initLock)
{
if (_mongoDbIndexHandler == null)
{
_mongoDbIndexHandler = new MongoDbIndexHandler(MongoDbContext);
}
}
return _mongoDbIndexHandler;
}
set { _mongoDbIndexHandler = value; }
}
/// <summary>
/// Returns the names of the indexes present on a collection.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="partitionKey">An optional partition key</param>
/// <returns>A list containing the names of the indexes on on the concerned collection.</returns>
public async Task<List<string>> GetIndexesNamesAsync<TDocument>(string partitionKey = null)
where TDocument : IDocument<Guid>
{
return await MongoDbIndexHandler.GetIndexesNamesAsync<TDocument, Guid>(partitionKey);
}
/// <summary>
/// Returns the names of the indexes present on a collection.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="partitionKey">An optional partition key</param>
/// <returns>A list containing the names of the indexes on on the concerned collection.</returns>
public async virtual Task<List<string>> GetIndexesNamesAsync<TDocument, TKey>(string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbIndexHandler.GetIndexesNamesAsync<TDocument, TKey>(partitionKey);
}
/// <summary>
/// Create a text index on the given field.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async Task<string> CreateTextIndexAsync<TDocument>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return await MongoDbIndexHandler.CreateTextIndexAsync<TDocument, Guid>(field, indexCreationOptions, partitionKey);
}
/// <summary>
/// Create a text index on the given field.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async virtual Task<string> CreateTextIndexAsync<TDocument, TKey>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbIndexHandler.CreateTextIndexAsync<TDocument, TKey>(field, indexCreationOptions, partitionKey);
}
/// <summary>
/// Creates an index on the given field in ascending order.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async Task<string> CreateAscendingIndexAsync<TDocument>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return await MongoDbIndexHandler.CreateAscendingIndexAsync<TDocument, Guid>(field, indexCreationOptions, partitionKey);
}
/// <summary>
/// Creates an index on the given field in ascending order.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async virtual Task<string> CreateAscendingIndexAsync<TDocument, TKey>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbIndexHandler.CreateAscendingIndexAsync<TDocument, TKey>(field, indexCreationOptions, partitionKey);
}
/// <summary>
/// Creates an index on the given field in descending order.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async Task<string> CreateDescendingIndexAsync<TDocument>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return await MongoDbIndexHandler.CreateDescendingIndexAsync<TDocument, Guid>(field, indexCreationOptions, partitionKey);
}
/// <inheritdoc />
public async virtual Task<string> CreateDescendingIndexAsync<TDocument, TKey>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbIndexHandler.CreateDescendingIndexAsync<TDocument, TKey>(field, indexCreationOptions, partitionKey);
}
/// <summary>
/// Creates a hashed index on the given field.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async Task<string> CreateHashedIndexAsync<TDocument>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return await MongoDbIndexHandler.CreateHashedIndexAsync<TDocument, Guid>(field, indexCreationOptions, partitionKey);
}
/// <inheritdoc />
public async virtual Task<string> CreateHashedIndexAsync<TDocument, TKey>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbIndexHandler.CreateHashedIndexAsync<TDocument, TKey>(field, indexCreationOptions, partitionKey);
}
/// <summary>
/// Creates a combined text index.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="fields">The fields we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async Task<string> CreateCombinedTextIndexAsync<TDocument>(IEnumerable<Expression<Func<TDocument, object>>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return await MongoDbIndexHandler.CreateCombinedTextIndexAsync<TDocument, Guid>(fields, indexCreationOptions, partitionKey);
}
/// <inheritdoc />
public async virtual Task<string> CreateCombinedTextIndexAsync<TDocument, TKey>(IEnumerable<Expression<Func<TDocument, object>>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbIndexHandler.CreateCombinedTextIndexAsync<TDocument, TKey>(fields, indexCreationOptions, partitionKey);
}
/// <summary>
/// Drops the index given a field name
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="indexName">The name of the index</param>
/// <param name="partitionKey">An optional partition key</param>
public async Task DropIndexAsync<TDocument>(string indexName, string partitionKey = null)
where TDocument : IDocument<Guid>
{
await MongoDbIndexHandler.DropIndexAsync<TDocument, Guid>(indexName, partitionKey);
}
/// <inheritdoc />
public async virtual Task DropIndexAsync<TDocument, TKey>(string indexName, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
await MongoDbIndexHandler.DropIndexAsync<TDocument, TKey>(indexName, partitionKey);
}
}
}
@@ -0,0 +1,177 @@
using MongoDB.Driver;
using MongoDbGenericRepository.Models;
using MongoDbGenericRepository.Utils;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace MongoDbGenericRepository
{
/// <summary>
/// The base Repository, it is meant to be inherited from by your custom custom MongoRepository implementation.
/// Its constructor must be given a connection string and a database name.
/// </summary>
public abstract partial class BaseMongoRepository : ReadOnlyMongoRepository, IBaseMongoRepository
{
/// <summary>
/// The constructor taking a connection string and a database name.
/// </summary>
/// <param name="connectionString">The connection string of the MongoDb server.</param>
/// <param name="databaseName">The name of the database against which you want to perform operations.</param>
protected BaseMongoRepository(string connectionString, string databaseName = null) : base(connectionString, databaseName)
{
}
/// <summary>
/// The contructor taking a <see cref="IMongoDbContext"/>.
/// </summary>
/// <param name="mongoDbContext">A mongodb context implementing <see cref="IMongoDbContext"/></param>
protected BaseMongoRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext)
{
}
/// <summary>
/// The contructor taking a <see cref="IMongoDatabase"/>.
/// </summary>
/// <param name="mongoDatabase">A mongodb context implementing <see cref="IMongoDatabase"/></param>
protected BaseMongoRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase)
{
}
/// <summary>
/// Asynchronously returns a paginated list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="skipNumber">The number of documents you want to skip. Default value is 0.</param>
/// <param name="takeNumber">The number of documents you want to take. Default value is 50.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual async Task<List<TDocument>> GetPaginatedAsync<TDocument>(
Expression<Func<TDocument, bool>> filter,
int skipNumber = 0,
int takeNumber = 50,
string partitionKey = null)
where TDocument : IDocument
{
return await HandlePartitioned<TDocument>(partitionKey).Find(filter).Skip(skipNumber).Limit(takeNumber).ToListAsync();
}
/// <summary>
/// Asynchronously returns a paginated list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="skipNumber">The number of documents you want to skip. Default value is 0.</param>
/// <param name="takeNumber">The number of documents you want to take. Default value is 50.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual async Task<List<TDocument>> GetPaginatedAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, int skipNumber = 0, int takeNumber = 50, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await HandlePartitioned<TDocument, TKey>(partitionKey).Find(filter).Skip(skipNumber).Limit(takeNumber).ToListAsync();
}
#region Find And Update
/// <summary>
/// GetAndUpdateOne with filter
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="update"></param>
/// <param name="options"></param>
/// <returns></returns>
public virtual async Task<TDocument> GetAndUpdateOne<TDocument>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> update, FindOneAndUpdateOptions<TDocument, TDocument> options) where TDocument : IDocument
{
return await GetCollection<TDocument>().FindOneAndUpdateAsync(filter, update, options);
}
/// <summary>
/// GetAndUpdateOne with filter
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="update"></param>
/// <param name="options"></param>
/// <returns></returns>
public virtual async Task<TDocument> GetAndUpdateOne<TDocument, TKey>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> update, FindOneAndUpdateOptions<TDocument, TDocument> options)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await GetCollection<TDocument, TKey>().FindOneAndUpdateAsync(filter, update, options);
}
#endregion Find And Update
/// <summary>
/// Sets the value of the document Id if it is not set already.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="document">The document.</param>
protected void FormatDocument<TDocument, TKey>(TDocument document)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
if (document == null)
{
throw new ArgumentNullException(nameof(document));
}
var defaultTKey = default(TKey);
if (document.Id == null
|| (defaultTKey != null
&& defaultTKey.Equals(document.Id)))
{
document.Id = IdGenerator.GetId<TKey>();
}
}
/// <summary>
/// Sets the value of the document Id if it is not set already.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="document">The document.</param>
protected void FormatDocument<TDocument>(TDocument document) where TDocument : IDocument
{
if (document == null)
{
throw new ArgumentNullException(nameof(document));
}
if (document.Id == default(Guid))
{
document.Id = Guid.NewGuid();
}
}
/// <summary>
/// Gets a collections for a potentially partitioned document type.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="partitionKey">The collection partition key.</param>
/// <returns></returns>
protected virtual IMongoCollection<TDocument> HandlePartitioned<TDocument>(string partitionKey)
where TDocument : IDocument<Guid>
{
if (!string.IsNullOrEmpty(partitionKey))
{
return GetCollection<TDocument>(partitionKey);
}
return GetCollection<TDocument>();
}
/// <summary>
/// Gets a collections for the type TDocument with a partition key.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="partitionKey">The collection partition key.</param>
/// <returns></returns>
protected virtual IMongoCollection<TDocument> GetCollection<TDocument>(string partitionKey = null)
where TDocument : IDocument<Guid>
{
return MongoDbContext.GetCollection<TDocument>(partitionKey);
}
}
}
@@ -0,0 +1,197 @@
using MongoDB.Driver;
using MongoDbGenericRepository.DataAccess.Update;
using MongoDbGenericRepository.Models;
using System;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
namespace MongoDbGenericRepository
{
public abstract partial class BaseMongoRepository : IBaseMongoRepository_Update_ClientSession
{
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey>(IClientSessionHandle session, TDocument modifiedDocument, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, TKey>(session, modifiedDocument, cancellationToken);
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
public virtual bool UpdateOne<TDocument, TKey>(IClientSessionHandle session, TDocument modifiedDocument, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbUpdater.UpdateOne<TDocument, TKey>(session, modifiedDocument, cancellationToken);
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="documentToModify">The document to modify.</param>
/// <param name="update">The update definition.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey>(IClientSessionHandle session, TDocument documentToModify, UpdateDefinition<TDocument> update, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, TKey>(session, documentToModify, update, cancellationToken);
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="documentToModify">The document to modify.</param>
/// <param name="update">The update definition.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
public virtual bool UpdateOne<TDocument, TKey>(IClientSessionHandle session, TDocument documentToModify, UpdateDefinition<TDocument> update, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbUpdater.UpdateOne<TDocument, TKey>(session, documentToModify, update, cancellationToken);
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="documentToModify">The document to modify.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey, TField>(IClientSessionHandle session, TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, TKey, TField>(session, documentToModify, field, value, cancellationToken);
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="documentToModify">The document to modify.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
public virtual bool UpdateOne<TDocument, TKey, TField>(IClientSessionHandle session, TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbUpdater.UpdateOne<TDocument, TKey, TField>(session, documentToModify, field, value, cancellationToken);
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="filter">The filter for the update.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="partitionKey">The optional partition key.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey, TField>(IClientSessionHandle session, FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, TKey, TField>(session, filter, field, value, partitionKey, cancellationToken);
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="filter">The filter for the update.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="partitionKey">The optional partition key.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey, TField>(IClientSessionHandle session, Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, TKey, TField>(session, filter, field, value, partitionKey, cancellationToken);
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="filter">The filter for the update.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="partitionKey">The optional partition key.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
public virtual bool UpdateOne<TDocument, TKey, TField>(IClientSessionHandle session, FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbUpdater.UpdateOne<TDocument, TKey, TField>(session, filter, field, value, partitionKey, cancellationToken);
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="filter">The filter for the update.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="partitionKey">The optional partition key.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns>A boolean value indicating success.</returns>
public virtual bool UpdateOne<TDocument, TKey, TField>(IClientSessionHandle session, Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return UpdateOne<TDocument, TKey, TField>(session, Builders<TDocument>.Filter.Where(filter), field, value, partitionKey, cancellationToken);
}
}
}
@@ -0,0 +1,573 @@
using MongoDB.Driver;
using MongoDbGenericRepository.DataAccess.Update;
using MongoDbGenericRepository.Models;
using System;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace MongoDbGenericRepository
{
/// <summary>
/// The base Repository, it is meant to be inherited from by your custom custom MongoRepository implementation.
/// Its constructor must be given a connection string and a database name.
/// </summary>
public abstract partial class BaseMongoRepository : IBaseMongoRepository_Update
{
private MongoDbUpdater _mongoDbUpdater;
protected virtual MongoDbUpdater MongoDbUpdater
{
get
{
if (_mongoDbUpdater != null) { return _mongoDbUpdater; }
lock (_initLock)
{
if (_mongoDbUpdater == null)
{
_mongoDbUpdater = new MongoDbUpdater(MongoDbContext);
}
}
return _mongoDbUpdater;
}
set { _mongoDbUpdater = value; }
}
#region Update
/// <summary>
/// Asynchronously Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument>(TDocument modifiedDocument) where TDocument : IDocument<Guid>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, Guid>(modifiedDocument);
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
public virtual bool UpdateOne<TDocument>(TDocument modifiedDocument) where TDocument : IDocument<Guid>
{
return MongoDbUpdater.UpdateOne<TDocument, Guid>(modifiedDocument);
}
/// <summary>
/// Takes a document you want to modify and applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="update">The update definition for the document.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument>(TDocument documentToModify, UpdateDefinition<TDocument> update)
where TDocument : IDocument<Guid>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, Guid>(documentToModify, update);
}
/// <summary>
/// Takes a document you want to modify and applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="update">The update definition for the document.</param>
public virtual bool UpdateOne<TDocument>(TDocument documentToModify, UpdateDefinition<TDocument> update)
where TDocument : IDocument<Guid>
{
return MongoDbUpdater.UpdateOne<TDocument, Guid>(documentToModify, update);
}
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
public virtual bool UpdateOne<TDocument, TField>(TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value)
where TDocument : IDocument<Guid>
{
return MongoDbUpdater.UpdateOne<TDocument, Guid, TField>(documentToModify, field, value);
}
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TField>(TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value)
where TDocument : IDocument<Guid>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, Guid, TField>(documentToModify, field, value);
}
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual bool UpdateOne<TDocument, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return MongoDbUpdater.UpdateOne<TDocument, Guid, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entity selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
public virtual bool UpdateOne<TDocument, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return MongoDbUpdater.UpdateOne<TDocument, Guid, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, Guid, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entity selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, Guid, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<long> UpdateManyAsync<TDocument, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return await MongoDbUpdater.UpdateManyAsync<TDocument, Guid, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<long> UpdateManyAsync<TDocument, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return await MongoDbUpdater.UpdateManyAsync<TDocument, Guid, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<long> UpdateManyAsync<TDocument>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return await MongoDbUpdater.UpdateManyAsync<TDocument, Guid>(filter, updateDefinition, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public async Task<long> UpdateManyAsync<TDocument>(Expression<Func<TDocument, bool>> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return await MongoDbUpdater.UpdateManyAsync<TDocument, Guid>(filter, updateDefinition, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual long UpdateMany<TDocument, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return MongoDbUpdater.UpdateMany<TDocument, Guid, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual long UpdateMany<TDocument, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return MongoDbUpdater.UpdateMany<TDocument, Guid, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual long UpdateMany<TDocument>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return MongoDbUpdater.UpdateMany<TDocument, Guid>(filter, updateDefinition, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public long UpdateMany<TDocument>(Expression<Func<TDocument, bool>> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<Guid>
{
return MongoDbUpdater.UpdateMany<TDocument, Guid>(filter, updateDefinition, partitionKey);
}
#endregion Update
#region Update TKey
/// <summary>
/// Asynchronously Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey>(TDocument modifiedDocument)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, TKey>(modifiedDocument);
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
public virtual bool UpdateOne<TDocument, TKey>(TDocument modifiedDocument)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbUpdater.UpdateOne<TDocument, TKey>(modifiedDocument);
}
/// <summary>
/// Takes a document you want to modify and applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="update">The update definition for the document.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey>(TDocument documentToModify, UpdateDefinition<TDocument> update)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, TKey>(documentToModify, update);
}
/// <summary>
/// Takes a document you want to modify and applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="update">The update definition for the document.</param>
public virtual bool UpdateOne<TDocument, TKey>(TDocument documentToModify, UpdateDefinition<TDocument> update)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbUpdater.UpdateOne<TDocument, TKey>(documentToModify, update);
}
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
public virtual bool UpdateOne<TDocument, TKey, TField>(TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbUpdater.UpdateOne<TDocument, TKey, TField>(documentToModify, field, value);
}
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey, TField>(TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, TKey, TField>(documentToModify, field, value);
}
/// <summary>
/// Updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual bool UpdateOne<TDocument, TKey, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbUpdater.UpdateOne<TDocument, TKey, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entity selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
public virtual bool UpdateOne<TDocument, TKey, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbUpdater.UpdateOne<TDocument, TKey, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, TKey, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entity selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, TKey, TField>(Builders<TDocument>.Filter.Where(filter), field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
public virtual async Task<long> UpdateManyAsync<TDocument, TKey, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbUpdater.UpdateManyAsync<TDocument, TKey, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<long> UpdateManyAsync<TDocument, TKey, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbUpdater.UpdateManyAsync<TDocument, TKey, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<long> UpdateManyAsync<TDocument, TKey>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbUpdater.UpdateManyAsync<TDocument, TKey>(filter, updateDefinition, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<long> UpdateManyAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await MongoDbUpdater.UpdateManyAsync<TDocument, TKey>(filter, updateDefinition, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
public virtual long UpdateMany<TDocument, TKey, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbUpdater.UpdateMany<TDocument, TKey, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual long UpdateMany<TDocument, TKey, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbUpdater.UpdateMany<TDocument, TKey, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual long UpdateMany<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbUpdater.UpdateMany<TDocument, TKey>(filter, updateDefinition, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual long UpdateMany<TDocument, TKey>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbUpdater.UpdateMany<TDocument, TKey>(filter, updateDefinition, partitionKey);
}
#endregion Update
}
}
@@ -0,0 +1,175 @@
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using MongoDbGenericRepository.Models;
using System;
using System.Linq;
using System.Linq.Expressions;
namespace MongoDbGenericRepository.DataAccess.Base
{
/// <summary>
/// A base class for accessing the Database and its Collections.
/// </summary>
public class DataAccessBase
{
/// <summary>
/// The MongoDbContext
/// </summary>
protected IMongoDbContext MongoDbContext;
/// <summary>
/// The constructor of the DataAccessBase class
/// </summary>
/// <param name="mongoDbContext"></param>
public DataAccessBase(IMongoDbContext mongoDbContext)
{
MongoDbContext = mongoDbContext;
}
#region Utility Methods
/// <summary>
/// Gets a IMongoQueryable for a potentially partitioned document type and a filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="filter">The filter definition.</param>
/// <param name="partitionKey">The collection partition key.</param>
/// <returns></returns>
public virtual IMongoQueryable<TDocument> GetQuery<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return GetCollection<TDocument, TKey>(partitionKey).AsQueryable().Where(filter);
}
/// <summary>
/// Gets a collections for a potentially partitioned document type.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="document">The document.</param>
/// <returns></returns>
public virtual IMongoCollection<TDocument> HandlePartitioned<TDocument, TKey>(TDocument document)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
if (document is IPartitionedDocument)
{
return GetCollection<TDocument, TKey>(((IPartitionedDocument)document).PartitionKey);
}
return GetCollection<TDocument, TKey>();
}
/// <summary>
/// Gets a collections for the type TDocument with a partition key.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="partitionKey">The collection partition key.</param>
/// <returns></returns>
public virtual IMongoCollection<TDocument> GetCollection<TDocument, TKey>(string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return MongoDbContext.GetCollection<TDocument>(partitionKey);
}
/// <summary>
/// Gets a collections for a potentially partitioned document type.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="partitionKey">The collection partition key.</param>
/// <returns></returns>
public virtual IMongoCollection<TDocument> HandlePartitioned<TDocument, TKey>(string partitionKey)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
if (!string.IsNullOrEmpty(partitionKey))
{
return GetCollection<TDocument, TKey>(partitionKey);
}
return GetCollection<TDocument, TKey>();
}
/// <summary>
/// Converts a LINQ expression of TDocument, TValue to a LINQ expression of TDocument, object
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <param name="expression">The expression to convert</param>
protected virtual Expression<Func<TDocument, object>> ConvertExpression<TDocument, TValue>(Expression<Func<TDocument, TValue>> expression)
{
var param = expression.Parameters[0];
Expression body = expression.Body;
var convert = Expression.Convert(body, typeof(object));
return Expression.Lambda<Func<TDocument, object>>(convert, param);
}
/// <summary>
/// Maps a IndexCreationOptions object to a MongoDB.Driver.CreateIndexOptions object
/// </summary>
/// <param name="indexCreationOptions">The options for creating an index.</param>
/// <returns></returns>
protected virtual CreateIndexOptions MapIndexOptions(IndexCreationOptions indexCreationOptions)
{
return new CreateIndexOptions
{
Unique = indexCreationOptions.Unique,
TextIndexVersion = indexCreationOptions.TextIndexVersion,
SphereIndexVersion = indexCreationOptions.SphereIndexVersion,
Sparse = indexCreationOptions.Sparse,
Name = indexCreationOptions.Name,
Min = indexCreationOptions.Min,
Max = indexCreationOptions.Max,
LanguageOverride = indexCreationOptions.LanguageOverride,
ExpireAfter = indexCreationOptions.ExpireAfter,
DefaultLanguage = indexCreationOptions.DefaultLanguage,
Bits = indexCreationOptions.Bits,
Background = indexCreationOptions.Background,
Version = indexCreationOptions.Version
};
}
/// <summary>
/// Gets the minimum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partition key.</param>
protected virtual IFindFluent<TDocument, TDocument> GetMinMongoQuery<TDocument, TKey, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return GetCollection<TDocument, TKey>(partitionKey).Find(Builders<TDocument>.Filter.Where(filter))
.SortBy(ConvertExpression(minValueSelector))
.Limit(1);
}
/// <summary>
/// Gets the minimum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="maxValueSelector">A property selector to order by descending.</param>
/// <param name="partitionKey">An optional partition key.</param>
protected virtual IFindFluent<TDocument, TDocument> GetMaxMongoQuery<TDocument, TKey, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> maxValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return GetCollection<TDocument, TKey>(partitionKey).Find(Builders<TDocument>.Filter.Where(filter))
.SortByDescending(ConvertExpression(maxValueSelector))
.Limit(1);
}
#endregion
}
}
@@ -0,0 +1,152 @@
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using MongoDbGenericRepository.DataAccess.Base;
using MongoDbGenericRepository.Models;
using MongoDbGenericRepository.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace MongoDbGenericRepository.DataAccess.Create
{
/// <summary>
/// A class to insert MongoDb document.
/// </summary>
public class MongoDbCreator : DataAccessBase
{
/// <summary>
/// The construct of the MongoDbCreator class.
/// </summary>
/// <param name="mongoDbContext">A <see cref="IMongoDbContext"/> instance.</param>
public MongoDbCreator(IMongoDbContext mongoDbContext) : base(mongoDbContext)
{
}
#region Create TKey
/// <summary>
/// Asynchronously adds a document to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="document">The document you want to add.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task AddOneAsync<TDocument, TKey>(TDocument document, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
FormatDocument<TDocument, TKey>(document);
await HandlePartitioned<TDocument, TKey>(document).InsertOneAsync(document, null, cancellationToken);
}
/// <summary>
/// Adds a document to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="document">The document you want to add.</param>
public virtual void AddOne<TDocument, TKey>(TDocument document)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
FormatDocument<TDocument, TKey>(document);
HandlePartitioned<TDocument, TKey>(document).InsertOne(document);
}
/// <summary>
/// Asynchronously adds a list of documents to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documents">The documents you want to add.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task AddManyAsync<TDocument, TKey>(IEnumerable<TDocument> documents, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
if (!documents.Any())
{
return;
}
foreach (var document in documents)
{
FormatDocument<TDocument, TKey>(document);
}
// cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5
if (documents.Any(e => e is IPartitionedDocument))
{
foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey))
{
await HandlePartitioned<TDocument, TKey>(group.FirstOrDefault()).InsertManyAsync(group.ToList(), null, cancellationToken);
}
}
else
{
await GetCollection<TDocument, TKey>().InsertManyAsync(documents.ToList(), null, cancellationToken);
}
}
/// <summary>
/// Adds a list of documents to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documents">The documents you want to add.</param>
public virtual void AddMany<TDocument, TKey>(IEnumerable<TDocument> documents)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
if (!documents.Any())
{
return;
}
foreach (var document in documents)
{
FormatDocument<TDocument, TKey>(document);
}
// cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5
if (documents.Any(e => e is IPartitionedDocument))
{
foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey))
{
HandlePartitioned<TDocument, TKey>(group.FirstOrDefault()).InsertMany(group.ToList());
}
}
else
{
GetCollection<TDocument, TKey>().InsertMany(documents.ToList());
}
}
#endregion
/// <summary>
/// Sets the value of the document Id if it is not set already.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="document">The document.</param>
protected void FormatDocument<TDocument, TKey>(TDocument document)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
if (document == null)
{
throw new ArgumentNullException(nameof(document));
}
var defaultTKey = default(TKey);
if (document.Id == null
|| (defaultTKey != null
&& defaultTKey.Equals(document.Id)))
{
document.Id = IdGenerator.GetId<TKey>();
}
}
}
}
@@ -0,0 +1,180 @@
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using MongoDbGenericRepository.DataAccess.Base;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace MongoDbGenericRepository.DataAccess.Delete
{
public class MongoDbEraser : DataAccessBase
{
public MongoDbEraser(IMongoDbContext mongoDbContext) : base(mongoDbContext)
{
}
#region Delete TKey
/// <summary>
/// Deletes a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="document">The document you want to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteOne<TDocument, TKey>(TDocument document)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", document.Id);
return HandlePartitioned<TDocument, TKey>(document).DeleteOne(filter).DeletedCount;
}
/// <summary>
/// Asynchronously deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="document">The document you want to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteOneAsync<TDocument, TKey>(TDocument document)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", document.Id);
return (await HandlePartitioned<TDocument, TKey>(document).DeleteOneAsync(filter)).DeletedCount;
}
/// <summary>
/// Deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteOne<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return HandlePartitioned<TDocument, TKey>(partitionKey).DeleteOne(filter).DeletedCount;
}
/// <summary>
/// Asynchronously deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteOneAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return (await HandlePartitioned<TDocument, TKey>(partitionKey).DeleteOneAsync(filter)).DeletedCount;
}
/// <summary>
/// Asynchronously deletes the documents matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteManyAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return (await HandlePartitioned<TDocument, TKey>(partitionKey).DeleteManyAsync(filter)).DeletedCount;
}
/// <summary>
/// Asynchronously deletes a list of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documents">The list of documents to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteManyAsync<TDocument, TKey>(IEnumerable<TDocument> documents)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
if (!documents.Any())
{
return 0;
}
// cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5
if (documents.Any(e => e is IPartitionedDocument))
{
long deleteCount = 0;
foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey))
{
var groupIdsTodelete = group.Select(e => e.Id).ToArray();
deleteCount += (await HandlePartitioned<TDocument, TKey>(group.FirstOrDefault()).DeleteManyAsync(x => groupIdsTodelete.Contains(x.Id))).DeletedCount;
}
return deleteCount;
}
else
{
var idsTodelete = documents.Select(e => e.Id).ToArray();
return (await HandlePartitioned<TDocument, TKey>(documents.FirstOrDefault()).DeleteManyAsync(x => idsTodelete.Contains(x.Id))).DeletedCount;
}
}
/// <summary>
/// Deletes a list of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documents">The list of documents to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteMany<TDocument, TKey>(IEnumerable<TDocument> documents)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
if (!documents.Any())
{
return 0;
}
// cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5
if (documents.Any(e => e is IPartitionedDocument))
{
long deleteCount = 0;
foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey))
{
var groupIdsTodelete = group.Select(e => e.Id).ToArray();
deleteCount += (HandlePartitioned<TDocument, TKey>(group.FirstOrDefault()).DeleteMany(x => groupIdsTodelete.Contains(x.Id))).DeletedCount;
}
return deleteCount;
}
else
{
var idsTodelete = documents.Select(e => e.Id).ToArray();
return (HandlePartitioned<TDocument, TKey>(documents.FirstOrDefault()).DeleteMany(x => idsTodelete.Contains(x.Id))).DeletedCount;
}
}
/// <summary>
/// Deletes the documents matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteMany<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return HandlePartitioned<TDocument, TKey>(partitionKey).DeleteMany(filter).DeletedCount;
}
#endregion
}
}
@@ -0,0 +1,167 @@
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using MongoDbGenericRepository.DataAccess.Base;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace MongoDbGenericRepository.DataAccess.Index
{
public class MongoDbIndexHandler : DataAccessBase
{
public MongoDbIndexHandler(IMongoDbContext mongoDbContext) : base(mongoDbContext)
{
}
/// <summary>
/// Returns the names of the indexes present on a collection.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="partitionKey">An optional partition key</param>
/// <returns>A list containing the names of the indexes on on the concerned collection.</returns>
public async virtual Task<List<string>> GetIndexesNamesAsync<TDocument, TKey>(string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var indexCursor = await HandlePartitioned<TDocument, TKey>(partitionKey).Indexes.ListAsync();
var indexes = await indexCursor.ToListAsync();
return indexes.Select(e => e["name"].ToString()).ToList();
}
/// <summary>
/// Create a text index on the given field.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async virtual Task<string> CreateTextIndexAsync<TDocument, TKey>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await HandlePartitioned<TDocument, TKey>(partitionKey).Indexes
.CreateOneAsync(
new CreateIndexModel<TDocument>(
Builders<TDocument>.IndexKeys.Text(field),
indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions)
));
}
/// <summary>
/// Creates an index on the given field in ascending order.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async virtual Task<string> CreateAscendingIndexAsync<TDocument, TKey>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var collection = HandlePartitioned<TDocument, TKey>(partitionKey);
var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions);
var indexKey = Builders<TDocument>.IndexKeys;
return await collection.Indexes
.CreateOneAsync(
new CreateIndexModel<TDocument>(indexKey.Ascending(field), createOptions));
}
/// <summary>
/// Creates an index on the given field in descending order.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async virtual Task<string> CreateDescendingIndexAsync<TDocument, TKey>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var collection = HandlePartitioned<TDocument, TKey>(partitionKey);
var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions);
var indexKey = Builders<TDocument>.IndexKeys;
return await collection.Indexes
.CreateOneAsync(
new CreateIndexModel<TDocument>(indexKey.Descending(field), createOptions));
}
/// <summary>
/// Creates a hashed index on the given field.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async virtual Task<string> CreateHashedIndexAsync<TDocument, TKey>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var collection = HandlePartitioned<TDocument, TKey>(partitionKey);
var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions);
var indexKey = Builders<TDocument>.IndexKeys;
return await collection.Indexes
.CreateOneAsync(
new CreateIndexModel<TDocument>(indexKey.Hashed(field), createOptions));
}
/// <summary>
/// Creates a combined text index.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="fields">The fields we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async virtual Task<string> CreateCombinedTextIndexAsync<TDocument, TKey>(IEnumerable<Expression<Func<TDocument, object>>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var collection = HandlePartitioned<TDocument, TKey>(partitionKey);
var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions);
var listOfDefs = new List<IndexKeysDefinition<TDocument>>();
foreach (var field in fields)
{
listOfDefs.Add(Builders<TDocument>.IndexKeys.Text(field));
}
return await collection.Indexes
.CreateOneAsync(new CreateIndexModel<TDocument>(Builders<TDocument>.IndexKeys.Combine(listOfDefs), createOptions));
}
/// <summary>
/// Drops the index given a field name
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="indexName">The name of the index</param>
/// <param name="partitionKey">An optional partition key</param>
public async virtual Task DropIndexAsync<TDocument, TKey>(string indexName, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
await HandlePartitioned<TDocument, TKey>(partitionKey).Indexes.DropOneAsync(indexName);
}
}
}
@@ -0,0 +1,569 @@
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using MongoDbGenericRepository.DataAccess.Base;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
namespace MongoDbGenericRepository.DataAccess.Read
{
/// <summary>
/// A class to read MongoDb document.
/// </summary>
public partial class MongoDbReader : DataAccessBase
{
/// <summary>
/// The construct of the MongoDbReader class.
/// </summary>
/// <param name="mongoDbContext">A <see cref="IMongoDbContext"/> instance.</param>
public MongoDbReader(IMongoDbContext mongoDbContext) : base(mongoDbContext)
{
}
#region Read TKey
/// <summary>
/// Asynchronously returns one document given its id.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="id">The Id of the document you want to get.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public async virtual Task<TDocument> GetByIdAsync<TDocument, TKey>(TKey id, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", id);
return await HandlePartitioned<TDocument, TKey>(partitionKey).Find(filter).FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
/// Returns one document given its id.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="id">The Id of the document you want to get.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual TDocument GetById<TDocument, TKey>(TKey id, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", id);
return HandlePartitioned<TDocument, TKey>(partitionKey).Find(filter).FirstOrDefault();
}
/// <summary>
/// Asynchronously returns one document given an expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public async virtual Task<TDocument> GetOneAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await HandlePartitioned<TDocument, TKey>(partitionKey).Find(filter).FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
/// Returns one document given an expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual TDocument GetOne<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return HandlePartitioned<TDocument, TKey>(partitionKey).Find(filter).FirstOrDefault();
}
/// <summary>
/// Returns a collection cursor.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual IFindFluent<TDocument, TDocument> GetCursor<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return HandlePartitioned<TDocument, TKey>(partitionKey).Find(filter);
}
/// <summary>
/// Returns true if any of the document of the collection matches the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public async virtual Task<bool> AnyAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var count = await HandlePartitioned<TDocument, TKey>(partitionKey).CountDocumentsAsync(filter, cancellationToken: cancellationToken);
return (count > 0);
}
/// <summary>
/// Returns true if any of the document of the collection matches the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual bool Any<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var count = HandlePartitioned<TDocument, TKey>(partitionKey).CountDocuments(filter);
return (count > 0);
}
/// <summary>
/// Asynchronously returns a list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public async virtual Task<List<TDocument>> GetAllAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await HandlePartitioned<TDocument, TKey>(partitionKey).Find(filter).ToListAsync(cancellationToken);
}
/// <summary>
/// Returns a list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual List<TDocument> GetAll<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return HandlePartitioned<TDocument, TKey>(partitionKey).Find(filter).ToList();
}
/// <summary>
/// Asynchronously counts how many documents match the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partitionKey</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public async virtual Task<long> CountAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await HandlePartitioned<TDocument, TKey>(partitionKey).CountDocumentsAsync(filter, cancellationToken: cancellationToken);
}
/// <summary>
/// Counts how many documents match the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partitionKey</param>
public virtual long Count<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return HandlePartitioned<TDocument, TKey>(partitionKey).Find(filter).CountDocuments();
}
#endregion
#region Min / Max
/// <summary>
/// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="maxValueSelector">A property selector to order by descending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public async virtual Task<TDocument> GetByMaxAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, object>> maxValueSelector, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await GetCollection<TDocument, TKey>(partitionKey).Find(Builders<TDocument>.Filter.Where(filter))
.SortByDescending(maxValueSelector)
.Limit(1)
.FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
/// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="maxValueSelector">A property selector to order by descending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
public virtual TDocument GetByMax<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, object>> maxValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return GetCollection<TDocument, TKey>(partitionKey).Find(Builders<TDocument>.Filter.Where(filter))
.SortByDescending(maxValueSelector)
.Limit(1)
.FirstOrDefault();
}
/// <summary>
/// Gets the document with the minimum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public async virtual Task<TDocument> GetByMinAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, object>> minValueSelector, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await GetCollection<TDocument, TKey>(partitionKey).Find(Builders<TDocument>.Filter.Where(filter))
.SortBy(minValueSelector)
.Limit(1)
.FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
/// Gets the document with the minimum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
public virtual TDocument GetByMin<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, object>> minValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return GetCollection<TDocument, TKey>(partitionKey).Find(Builders<TDocument>.Filter.Where(filter))
.SortBy(minValueSelector)
.Limit(1)
.FirstOrDefault();
}
/// <summary>
/// Gets the maximum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <typeparam name="TValue">The type of the field for which you want the maximum value.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="maxValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public async virtual Task<TValue> GetMaxValueAsync<TDocument, TKey, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> maxValueSelector, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await GetMaxMongoQuery<TDocument, TKey, TValue>(filter, maxValueSelector, partitionKey)
.Project(maxValueSelector)
.FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
/// Gets the maximum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="maxValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
public virtual TValue GetMaxValue<TDocument, TKey, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> maxValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return GetMaxMongoQuery<TDocument, TKey, TValue>(filter, maxValueSelector, partitionKey)
.Project(maxValueSelector)
.FirstOrDefault();
}
/// <summary>
/// Gets the minimum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task<TValue> GetMinValueAsync<TDocument, TKey, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await GetMinMongoQuery<TDocument, TKey, TValue>(filter, minValueSelector, partitionKey).Project(minValueSelector).FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
/// Gets the minimum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TKey">The type of the primary key.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual TValue GetMinValue<TDocument, TKey, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return GetMinMongoQuery<TDocument, TKey, TValue>(filter, minValueSelector, partitionKey).Project(minValueSelector).FirstOrDefault();
}
#endregion Min / Max
#region Sum TKey
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task<int> SumByAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, int>> selector,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await GetQuery<TDocument, TKey>(filter, partitionKey).SumAsync(selector, cancellationToken);
}
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
public virtual int SumBy<TDocument, TKey>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, int>> selector,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return GetQuery<TDocument, TKey>(filter, partitionKey).Sum(selector);
}
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task<decimal> SumByAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, decimal>> selector,
string partitionKey = null, CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await GetQuery<TDocument, TKey>(filter, partitionKey).SumAsync(selector, cancellationToken);
}
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
public virtual decimal SumBy<TDocument, TKey>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, decimal>> selector,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return GetQuery<TDocument, TKey>(filter, partitionKey).Sum(selector);
}
#endregion Sum TKey
}
public partial class MongoDbReader
{
/// <summary>
/// Groups a collection of documents given a grouping criteria,
/// and returns a dictionary of listed document groups with keys having the different values of the grouping criteria.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TGroupKey">The type of the grouping criteria.</typeparam>
/// <typeparam name="TProjection">The type of the projected group.</typeparam>
/// <param name="groupingCriteria">The grouping criteria.</param>
/// <param name="groupProjection">The projected group result.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
public virtual List<TProjection> GroupBy<TDocument, TGroupKey, TProjection, TKey>(
Expression<Func<TDocument, TGroupKey>> groupingCriteria,
Expression<Func<IGrouping<TGroupKey, TDocument>, TProjection>> groupProjection,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
where TProjection : class, new()
{
return HandlePartitioned<TDocument, TKey>(partitionKey)
.Aggregate()
.Group(groupingCriteria, groupProjection)
.ToList();
}
/// <summary>
/// Groups filtered a collection of documents given a grouping criteria,
/// and returns a dictionary of listed document groups with keys having the different values of the grouping criteria.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TGroupKey">The type of the grouping criteria.</typeparam>
/// <typeparam name="TProjection">The type of the projected group.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The grouping criteria.</param>
/// <param name="projection">The projected group result.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
public virtual List<TProjection> GroupBy<TDocument, TGroupKey, TProjection, TKey>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, TGroupKey>> selector,
Expression<Func<IGrouping<TGroupKey, TDocument>, TProjection>> projection,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
where TProjection : class, new()
{
var collection = HandlePartitioned<TDocument, TKey>(partitionKey);
return collection.Aggregate()
.Match(Builders<TDocument>.Filter.Where(filter))
.Group(selector, projection)
.ToList();
}
/// <summary>
/// Groups filtered a collection of documents given a grouping criteria,
/// and returns a dictionary of listed document groups with keys having the different values of the grouping criteria.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TGroupKey">The type of the grouping criteria.</typeparam>
/// <typeparam name="TProjection">The type of the projected group.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The grouping criteria.</param>
/// <param name="projection">The projected group result.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task<List<TProjection>> GroupByAsync<TDocument, TGroupKey, TProjection, TKey>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, TGroupKey>> selector,
Expression<Func<IGrouping<TGroupKey, TDocument>, TProjection>> projection,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
where TProjection : class, new()
{
var collection = HandlePartitioned<TDocument, TKey>(partitionKey);
return await collection.Aggregate()
.Match(Builders<TDocument>.Filter.Where(filter))
.Group(selector, projection)
.ToListAsync(cancellationToken);
}
/// <summary>
/// Asynchronously returns a paginated list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="sortSelector">The property selector.</param>
/// <param name="ascending">Order of the sorting.</param>
/// <param name="skipNumber">The number of documents you want to skip. Default value is 0.</param>
/// <param name="takeNumber">The number of documents you want to take. Default value is 50.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task<List<TDocument>> GetSortedPaginatedAsync<TDocument, TKey>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, object>> sortSelector,
bool ascending = true,
int skipNumber = 0,
int takeNumber = 50,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var sorting = ascending
? Builders<TDocument>.Sort.Ascending(sortSelector)
: Builders<TDocument>.Sort.Descending(sortSelector);
return await HandlePartitioned<TDocument, TKey>(partitionKey)
.Find(filter)
.Sort(sorting)
.Skip(skipNumber)
.Limit(takeNumber)
.ToListAsync(cancellationToken);
}
/// <summary>
/// Asynchronously returns a paginated list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="sortDefinition">The sort definition.</param>
/// <param name="skipNumber">The number of documents you want to skip. Default value is 0.</param>
/// <param name="takeNumber">The number of documents you want to take. Default value is 50.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task<List<TDocument>> GetSortedPaginatedAsync<TDocument, TKey>(
Expression<Func<TDocument, bool>> filter,
SortDefinition<TDocument> sortDefinition,
int skipNumber = 0,
int takeNumber = 50,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await HandlePartitioned<TDocument, TKey>(partitionKey)
.Find(filter)
.Sort(sortDefinition)
.Skip(skipNumber)
.Limit(takeNumber)
.ToListAsync(cancellationToken);
}
}
}
@@ -0,0 +1,101 @@
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
namespace MongoDbGenericRepository.DataAccess.Read
{
public partial class MongoDbReader
{
/// <summary>
/// Asynchronously returns a projected document matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task<TProjection> ProjectOneAsync<TDocument, TProjection, TKey>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, TProjection>> projection,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
where TProjection : class
{
return await HandlePartitioned<TDocument, TKey>(partitionKey).Find(filter)
.Project(projection)
.FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
/// Returns a projected document matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual TProjection ProjectOne<TDocument, TProjection, TKey>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
where TProjection : class
{
return HandlePartitioned<TDocument, TKey>(partitionKey).Find(filter)
.Project(projection)
.FirstOrDefault();
}
/// <summary>
/// Asynchronously returns a list of projected documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task<List<TProjection>> ProjectManyAsync<TDocument, TProjection, TKey>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, TProjection>> projection,
string partitionKey = null,
CancellationToken cancellationToken = default)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
where TProjection : class
{
return await HandlePartitioned<TDocument, TKey>(partitionKey).Find(filter)
.Project(projection)
.ToListAsync(cancellationToken);
}
/// <summary>
/// Asynchronously returns a list of projected documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual List<TProjection> ProjectMany<TDocument, TProjection, TKey>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
where TProjection : class
{
return HandlePartitioned<TDocument, TKey>(partitionKey).Find(filter)
.Project(projection)
.ToList();
}
}
}
@@ -0,0 +1,217 @@
using MongoDB.Driver;
using MongoDbGenericRepository.Models;
using System;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
namespace MongoDbGenericRepository.DataAccess.Update
{
public partial class MongoDbUpdater
{
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns></returns>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey>(IClientSessionHandle session, TDocument modifiedDocument, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", modifiedDocument.Id);
var updateRes = await HandlePartitioned<TDocument, TKey>(modifiedDocument)
.ReplaceOneAsync(session, filter, modifiedDocument, cancellationToken: cancellationToken)
.ConfigureAwait(false);
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns></returns>
public virtual bool UpdateOne<TDocument, TKey>(IClientSessionHandle session, TDocument modifiedDocument, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", modifiedDocument.Id);
var updateRes = HandlePartitioned<TDocument, TKey>(modifiedDocument).ReplaceOne(session, filter, modifiedDocument, cancellationToken: cancellationToken);
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="documentToModify">The document to modify.</param>
/// <param name="update">The update definition.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns></returns>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey>(IClientSessionHandle session, TDocument documentToModify, UpdateDefinition<TDocument> update, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", documentToModify.Id);
var updateRes = await HandlePartitioned<TDocument, TKey>(documentToModify).UpdateOneAsync(session, filter, update, null, cancellationToken).ConfigureAwait(false);
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="documentToModify">The document to modify.</param>
/// <param name="update">The update definition.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns></returns>
public virtual bool UpdateOne<TDocument, TKey>(IClientSessionHandle session, TDocument documentToModify, UpdateDefinition<TDocument> update, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", documentToModify.Id);
var updateRes = HandlePartitioned<TDocument, TKey>(documentToModify).UpdateOne(session, filter, update, null, cancellationToken);
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="documentToModify">The document to modify.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns></returns>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey, TField>(IClientSessionHandle session, TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", documentToModify.Id);
var updateRes = await HandlePartitioned<TDocument, TKey>(documentToModify)
.UpdateOneAsync(session, filter, Builders<TDocument>.Update.Set(field, value), cancellationToken: cancellationToken)
.ConfigureAwait(false);
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="documentToModify">The document to modify.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns></returns>
public virtual bool UpdateOne<TDocument, TKey, TField>(IClientSessionHandle session, TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", documentToModify.Id);
var updateRes = HandlePartitioned<TDocument, TKey>(documentToModify).UpdateOne(session, filter, Builders<TDocument>.Update.Set(field, value), cancellationToken: cancellationToken);
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="filter">The filter for the update.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="partitionKey">The optional partition key.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns></returns>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey, TField>(IClientSessionHandle session, FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection<TDocument, TKey>() : GetCollection<TDocument, TKey>(partitionKey);
var updateRes = await collection.UpdateOneAsync(session, filter, Builders<TDocument>.Update.Set(field, value), cancellationToken: cancellationToken).ConfigureAwait(false);
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="filter">The filter for the update.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="partitionKey">The optional partition key.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns></returns>
public virtual Task<bool> UpdateOneAsync<TDocument, TKey, TField>(IClientSessionHandle session, Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return UpdateOneAsync<TDocument, TKey, TField>(session, Builders<TDocument>.Filter.Where(filter), field, value, partitionKey, cancellationToken);
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="filter">The filter for the update.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="partitionKey">The optional partition key.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns></returns>
public virtual bool UpdateOne<TDocument, TKey, TField>(IClientSessionHandle session, FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection<TDocument, TKey>() : GetCollection<TDocument, TKey>(partitionKey);
var updateRes = collection.UpdateOne(session, filter, Builders<TDocument>.Update.Set(field, value), cancellationToken: cancellationToken);
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field to update.</typeparam>
/// <param name="session">The client session.</param>
/// <param name="filter">The filter for the update.</param>
/// <param name="field">The field to update.</param>
/// <param name="value">The value of the field.</param>
/// <param name="partitionKey">The optional partition key.</param>
/// <param name="cancellationToken">The optional cancellation token.</param>
/// <returns></returns>
public virtual bool UpdateOne<TDocument, TKey, TField>(IClientSessionHandle session, Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null, CancellationToken cancellationToken = default(CancellationToken))
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return UpdateOne<TDocument, TKey, TField>(session, Builders<TDocument>.Filter.Where(filter), field, value, partitionKey, cancellationToken);
}
}
}
@@ -0,0 +1,311 @@
using MongoDB.Driver;
using MongoDbGenericRepository.DataAccess.Base;
using MongoDbGenericRepository.Models;
using System;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
namespace MongoDbGenericRepository.DataAccess.Update
{
public partial class MongoDbUpdater : DataAccessBase
{
public MongoDbUpdater(IMongoDbContext mongoDbContext) : base(mongoDbContext)
{
}
/// <summary>
/// Asynchronously Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey>(TDocument modifiedDocument)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", modifiedDocument.Id);
var updateRes = await HandlePartitioned<TDocument, TKey>(modifiedDocument).ReplaceOneAsync(filter, modifiedDocument);
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
public virtual bool UpdateOne<TDocument, TKey>(TDocument modifiedDocument)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", modifiedDocument.Id);
var updateRes = HandlePartitioned<TDocument, TKey>(modifiedDocument).ReplaceOne(filter, modifiedDocument);
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// Takes a document you want to modify and applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="update">The update definition for the document.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey>(TDocument documentToModify, UpdateDefinition<TDocument> update)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", documentToModify.Id);
var updateRes = await HandlePartitioned<TDocument, TKey>(documentToModify).UpdateOneAsync(filter, update);
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// Takes a document you want to modify and applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="update">The update definition for the document.</param>
public virtual bool UpdateOne<TDocument, TKey>(TDocument documentToModify, UpdateDefinition<TDocument> update)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", documentToModify.Id);
var updateRes = HandlePartitioned<TDocument, TKey>(documentToModify).UpdateOne(filter, update);
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey, TField>(TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", documentToModify.Id);
var updateRes = await HandlePartitioned<TDocument, TKey>(documentToModify).UpdateOneAsync(filter, Builders<TDocument>.Update.Set(field, value));
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
public virtual bool UpdateOne<TDocument, TKey, TField>(TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var filter = Builders<TDocument>.Filter.Eq("Id", documentToModify.Id);
var updateRes = HandlePartitioned<TDocument, TKey>(documentToModify).UpdateOne(filter, Builders<TDocument>.Update.Set(field, value));
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection<TDocument, TKey>() : GetCollection<TDocument, TKey>(partitionKey);
var updateRes = await collection.UpdateOneAsync(filter, Builders<TDocument>.Update.Set(field, value));
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// For the entity selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TKey, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await UpdateOneAsync<TDocument, TKey, TField>(Builders<TDocument>.Filter.Where(filter), field, value, partitionKey);
}
/// <summary>
/// Updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual bool UpdateOne<TDocument, TKey, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection<TDocument, TKey>() : GetCollection<TDocument, TKey>(partitionKey);
var updateRes = collection.UpdateOne(filter, Builders<TDocument>.Update.Set(field, value));
return updateRes.ModifiedCount == 1;
}
/// <summary>
/// For the entity selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
public virtual bool UpdateOne<TDocument, TKey, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return UpdateOne<TDocument, TKey, TField>(Builders<TDocument>.Filter.Where(filter), field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
public virtual async Task<long> UpdateManyAsync<TDocument, TKey, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await UpdateManyAsync<TDocument, TKey, TField>(Builders<TDocument>.Filter.Where(filter), field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<long> UpdateManyAsync<TDocument, TKey, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection<TDocument, TKey>() : GetCollection<TDocument, TKey>(partitionKey);
var updateRes = await collection.UpdateManyAsync(filter, Builders<TDocument>.Update.Set(field, value));
return updateRes.ModifiedCount;
}
/// <summary>
/// For the entities selected by the filter, apply the update definition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<long> UpdateManyAsync<TDocument, TKey>(Expression<Func<TDocument, bool>> filter, UpdateDefinition<TDocument> update, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return await UpdateManyAsync<TDocument, TKey>(Builders<TDocument>.Filter.Where(filter), update, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, apply the update definition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<long> UpdateManyAsync<TDocument, TKey>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection<TDocument, TKey>() : GetCollection<TDocument, TKey>(partitionKey);
var updateRes = await collection.UpdateManyAsync(filter, updateDefinition);
return updateRes.ModifiedCount;
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
public virtual long UpdateMany<TDocument, TKey, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
return UpdateMany<TDocument, TKey, TField>(Builders<TDocument>.Filter.Where(filter), field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual long UpdateMany<TDocument, TKey, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection<TDocument, TKey>() : GetCollection<TDocument, TKey>(partitionKey);
var updateRes = collection.UpdateMany(filter, Builders<TDocument>.Update.Set(field, value));
return updateRes.ModifiedCount;
}
/// <summary>
/// For the entities selected by the filter, apply the update definition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="UpdateDefinition">The update definition.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual long UpdateMany<TDocument, TKey>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> UpdateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>
where TKey : IEquatable<TKey>
{
var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection<TDocument, TKey>() : GetCollection<TDocument, TKey>(partitionKey);
var updateRes = collection.UpdateMany(filter, UpdateDefinition);
return updateRes.ModifiedCount;
}
}
}
@@ -0,0 +1,127 @@
using MongoDbGenericRepository.DataAccess.Create;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace MongoDbGenericRepository
{
/// <summary>
/// The interface exposing data insertion functionality for Key typed repositories.
/// </summary>
/// <typeparam name="TKey"></typeparam>
public interface IBaseMongoRepository_Create<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// Asynchronously adds a document to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="document">The document you want to add.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task AddOneAsync<TDocument>(TDocument document, CancellationToken cancellationToken = default) where TDocument : IDocument<TKey>;
/// <summary>
/// Adds a document to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="document">The document you want to add.</param>
void AddOne<TDocument>(TDocument document) where TDocument : IDocument<TKey>;
/// <summary>
/// Asynchronously adds a list of documents to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documents">The documents you want to add.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
Task AddManyAsync<TDocument>(IEnumerable<TDocument> documents, CancellationToken cancellationToken = default) where TDocument : IDocument<TKey>;
/// <summary>
/// Adds a list of documents to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documents">The documents you want to add.</param>
void AddMany<TDocument>(IEnumerable<TDocument> documents) where TDocument : IDocument<TKey>;
}
/// <summary>
/// The base Repository, it is meant to be inherited from by your custom custom MongoRepository implementation.
/// Its constructor must be given a connection string and a database name.
/// </summary>
public abstract partial class BaseMongoRepository<TKey> : IBaseMongoRepository_Create<TKey> where TKey : IEquatable<TKey>
{
private MongoDbCreator _mongoDbCreator;
/// <summary>
/// The MongoDb accessor to insert data.
/// </summary>
protected virtual MongoDbCreator MongoDbCreator
{
get
{
if(_mongoDbCreator == null)
{
lock (_initLock)
{
if(_mongoDbCreator == null)
{
_mongoDbCreator = new MongoDbCreator(MongoDbContext);
}
}
}
return _mongoDbCreator;
}
set { _mongoDbCreator = value; }
}
/// <summary>
/// Asynchronously adds a document to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="document">The document you want to add.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task AddOneAsync<TDocument>(TDocument document, CancellationToken cancellationToken = default) where TDocument : IDocument<TKey>
{
await MongoDbCreator.AddOneAsync<TDocument, TKey>(document, cancellationToken);
}
/// <summary>
/// Adds a document to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="document">The document you want to add.</param>
public virtual void AddOne<TDocument>(TDocument document) where TDocument : IDocument<TKey>
{
MongoDbCreator.AddOne<TDocument, TKey>(document);
}
/// <summary>
/// Asynchronously adds a list of documents to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documents">The documents you want to add.</param>
/// <param name="cancellationToken">An optional cancellation Token.</param>
public virtual async Task AddManyAsync<TDocument>(IEnumerable<TDocument> documents, CancellationToken cancellationToken = default) where TDocument : IDocument<TKey>
{
await MongoDbCreator.AddManyAsync<TDocument, TKey>(documents, cancellationToken);
}
/// <summary>
/// Adds a list of documents to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documents">The documents you want to add.</param>
public virtual void AddMany<TDocument>(IEnumerable<TDocument> documents) where TDocument : IDocument<TKey>
{
MongoDbCreator.AddMany<TDocument, TKey>(documents);
}
}
}
@@ -0,0 +1,219 @@
using MongoDbGenericRepository.DataAccess.Delete;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace MongoDbGenericRepository
{
/// <summary>
/// The interface exposing deletion functionality for Key typed repositories.
/// </summary>
/// <typeparam name="TKey">The type of the document Id.</typeparam>
public interface IBaseMongoRepository_Delete<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// Deletes a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="document">The document you want to delete.</param>
/// <returns>The number of documents deleted.</returns>
long DeleteOne<TDocument>(TDocument document)
where TDocument : IDocument<TKey>;
/// <summary>
/// Asynchronously deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="document">The document you want to delete.</param>
/// <returns>The number of documents deleted.</returns>
Task<long> DeleteOneAsync<TDocument>(TDocument document)
where TDocument : IDocument<TKey>;
/// <summary>
/// Deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
long DeleteOne<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Asynchronously deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
Task<long> DeleteOneAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Asynchronously deletes the documents matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
Task<long> DeleteManyAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Asynchronously deletes a list of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documents">The list of documents to delete.</param>
/// <returns>The number of documents deleted.</returns>
Task<long> DeleteManyAsync<TDocument>(IEnumerable<TDocument> documents)
where TDocument : IDocument<TKey>;
/// <summary>
/// Deletes a list of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documents">The list of documents to delete.</param>
/// <returns>The number of documents deleted.</returns>
long DeleteMany<TDocument>(IEnumerable<TDocument> documents)
where TDocument : IDocument<TKey>;
/// <summary>
/// Deletes the documents matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
long DeleteMany<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>;
}
public abstract partial class BaseMongoRepository<TKey>: IBaseMongoRepository_Delete<TKey>
where TKey : IEquatable<TKey>
{
private MongoDbEraser _mongoDbEraser;
/// <summary>
/// The MongoDb accessor to delete data.
/// </summary>
protected virtual MongoDbEraser MongoDbEraser
{
get
{
if (_mongoDbEraser != null) { return _mongoDbEraser; }
lock (_initLock)
{
if (_mongoDbEraser == null)
{
_mongoDbEraser = new MongoDbEraser(MongoDbContext);
}
}
return _mongoDbEraser;
}
set { _mongoDbEraser = value; }
}
/// <summary>
/// Deletes a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="document">The document you want to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteOne<TDocument>(TDocument document)
where TDocument : IDocument<TKey>
{
return MongoDbEraser.DeleteOne<TDocument, TKey>(document);
}
/// <summary>
/// Asynchronously deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="document">The document you want to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteOneAsync<TDocument>(TDocument document)
where TDocument : IDocument<TKey>
{
return await MongoDbEraser.DeleteOneAsync<TDocument, TKey>(document);
}
/// <summary>
/// Deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteOne<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return MongoDbEraser.DeleteOne<TDocument, TKey>(filter, partitionKey);
}
/// <summary>
/// Asynchronously deletes a document matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteOneAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbEraser.DeleteOneAsync<TDocument, TKey>(filter, partitionKey);
}
/// <summary>
/// Asynchronously deletes the documents matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteManyAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbEraser.DeleteManyAsync<TDocument, TKey>(filter, partitionKey);
}
/// <summary>
/// Asynchronously deletes a list of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documents">The list of documents to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual async Task<long> DeleteManyAsync<TDocument>(IEnumerable<TDocument> documents)
where TDocument : IDocument<TKey>
{
return await MongoDbEraser.DeleteManyAsync<TDocument, TKey>(documents);
}
/// <summary>
/// Deletes a list of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documents">The list of documents to delete.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteMany<TDocument>(IEnumerable<TDocument> documents)
where TDocument : IDocument<TKey>
{
return MongoDbEraser.DeleteMany<TDocument, TKey>(documents);
}
/// <summary>
/// Deletes the documents matching the condition of the LINQ expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The number of documents deleted.</returns>
public virtual long DeleteMany<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return MongoDbEraser.DeleteMany<TDocument, TKey>(filter, partitionKey);
}
}
}
@@ -0,0 +1,234 @@
using MongoDbGenericRepository.DataAccess.Index;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace MongoDbGenericRepository
{
/// <summary>
/// The interface exposing index management functionality for Key typed repositories.
/// </summary>
/// <typeparam name="TKey"></typeparam>
public interface IBaseMongoRepository_Index<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// Returns the names of the indexes present on a collection.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="partitionKey">An optional partition key</param>
/// <returns>A list containing the names of the indexes on on the concerned collection.</returns>
Task<List<string>> GetIndexesNamesAsync<TDocument>(string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Create a text index on the given field.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
Task<string> CreateTextIndexAsync<TDocument>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Creates an index on the given field in ascending order.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
Task<string> CreateAscendingIndexAsync<TDocument>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Creates an index on the given field in descending order.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
Task<string> CreateDescendingIndexAsync<TDocument>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Creates a hashed index on the given field.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
Task<string> CreateHashedIndexAsync<TDocument>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Creates a combined text index.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="fields">The fields we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
Task<string> CreateCombinedTextIndexAsync<TDocument>(IEnumerable<Expression<Func<TDocument, object>>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Drops the index given a field name
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="indexName">The name of the index</param>
/// <param name="partitionKey">An optional partition key</param>
Task DropIndexAsync<TDocument>(string indexName, string partitionKey = null)
where TDocument : IDocument<TKey>;
}
/// <summary>
/// The base Repository, it is meant to be inherited from by your custom custom MongoRepository implementation.
/// Its constructor must be given a connection string and a database name.
/// </summary>
public abstract partial class BaseMongoRepository<TKey> : IBaseMongoRepository_Index<TKey>
where TKey : IEquatable<TKey>
{
private MongoDbIndexHandler _mongoDbIndexHandler;
/// <summary>
/// The MongoDb accessor to manage indexes.
/// </summary>
protected virtual MongoDbIndexHandler MongoDbIndexHandler
{
get
{
if (_mongoDbIndexHandler != null) { return _mongoDbIndexHandler; }
lock (_initLock)
{
if (_mongoDbIndexHandler == null)
{
_mongoDbIndexHandler = new MongoDbIndexHandler(MongoDbContext);
}
}
return _mongoDbIndexHandler;
}
set { _mongoDbIndexHandler = value; }
}
/// <summary>
/// Returns the names of the indexes present on a collection.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="partitionKey">An optional partition key</param>
/// <returns>A list containing the names of the indexes on on the concerned collection.</returns>
public async virtual Task<List<string>> GetIndexesNamesAsync<TDocument>(string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbIndexHandler.GetIndexesNamesAsync<TDocument, TKey>(partitionKey);
}
/// <summary>
/// Create a text index on the given field.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async virtual Task<string> CreateTextIndexAsync<TDocument>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbIndexHandler.CreateTextIndexAsync<TDocument, TKey>(field, indexCreationOptions, partitionKey);
}
/// <summary>
/// Creates an index on the given field in ascending order.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async virtual Task<string> CreateAscendingIndexAsync<TDocument>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbIndexHandler.CreateAscendingIndexAsync<TDocument, TKey>(field, indexCreationOptions, partitionKey);
}
/// <summary>
/// Creates an index on the given field in descending order.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async virtual Task<string> CreateDescendingIndexAsync<TDocument>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbIndexHandler.CreateDescendingIndexAsync<TDocument, TKey>(field, indexCreationOptions, partitionKey);
}
/// <summary>
/// Creates a hashed index on the given field.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="field">The field we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async virtual Task<string> CreateHashedIndexAsync<TDocument>(Expression<Func<TDocument, object>> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbIndexHandler.CreateHashedIndexAsync<TDocument, TKey>(field, indexCreationOptions, partitionKey);
}
/// <summary>
/// Creates a combined text index.
/// IndexCreationOptions can be supplied to further specify
/// how the creation should be done.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="fields">The fields we want to index.</param>
/// <param name="indexCreationOptions">Options for creating an index.</param>
/// <param name="partitionKey">An optional partition key.</param>
/// <returns>The result of the create index operation.</returns>
public async virtual Task<string> CreateCombinedTextIndexAsync<TDocument>(IEnumerable<Expression<Func<TDocument, object>>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbIndexHandler.CreateCombinedTextIndexAsync<TDocument, TKey>(fields, indexCreationOptions, partitionKey);
}
/// <summary>
/// Drops the index given a field name
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="indexName">The name of the index</param>
/// <param name="partitionKey">An optional partition key</param>
public async virtual Task DropIndexAsync<TDocument>(string indexName, string partitionKey = null)
where TDocument : IDocument<TKey>
{
await MongoDbIndexHandler.DropIndexAsync<TDocument, TKey>(indexName, partitionKey);
}
}
}
@@ -0,0 +1,87 @@
using MongoDB.Driver;
using MongoDbGenericRepository.Models;
using System;
namespace MongoDbGenericRepository
{
/// <summary>
/// The interface exposing all the CRUD and Index functionalities for Key typed repositories.
/// </summary>
/// <typeparam name="TKey">The type of the document Id.</typeparam>
public interface IBaseMongoRepository<TKey> :
IReadOnlyMongoRepository<TKey>,
IBaseMongoRepository_Create<TKey>,
IBaseMongoRepository_Delete<TKey>,
IBaseMongoRepository_Index<TKey>,
IBaseMongoRepository_Update<TKey>
where TKey : IEquatable<TKey>
{
}
/// <summary>
/// The base Repository, it is meant to be inherited from by your custom custom MongoRepository implementation.
/// Its constructor must be given a connection string and a database name.
/// </summary>
/// <typeparam name="TKey">The type of the document Id.</typeparam>
public abstract partial class BaseMongoRepository<TKey> :
ReadOnlyMongoRepository<TKey>,
IBaseMongoRepository<TKey>
where TKey : IEquatable<TKey>
{
private readonly object _initLock = new object();
/// <summary>
/// The constructor taking a connection string and a database name.
/// </summary>
/// <param name="connectionString">The connection string of the MongoDb server.</param>
/// <param name="databaseName">The name of the database against which you want to perform operations.</param>
protected BaseMongoRepository(string connectionString, string databaseName = null) : base(connectionString, databaseName)
{
}
/// <summary>
/// The contructor taking a <see cref="IMongoDbContext"/>.
/// </summary>
/// <param name="mongoDbContext">A mongodb context implementing <see cref="IMongoDbContext"/></param>
protected BaseMongoRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext)
{
}
/// <summary>
/// The contructor taking a <see cref="IMongoDatabase"/>.
/// </summary>
/// <param name="mongoDatabase">A mongodb context implementing <see cref="IMongoDatabase"/></param>
protected BaseMongoRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase)
{
}
/// <summary>
/// Gets a collections for a potentially partitioned document type.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="partitionKey">The collection partition key.</param>
/// <returns></returns>
protected virtual IMongoCollection<TDocument> HandlePartitioned<TDocument>(string partitionKey)
where TDocument : IDocument<TKey>
{
if (!string.IsNullOrEmpty(partitionKey))
{
return GetCollection<TDocument>(partitionKey);
}
return GetCollection<TDocument>();
}
/// <summary>
/// Gets a collections for the type TDocument with a partition key.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="partitionKey">The collection partition key.</param>
/// <returns></returns>
protected virtual IMongoCollection<TDocument> GetCollection<TDocument>(string partitionKey = null)
where TDocument : IDocument<TKey>
{
return MongoDbContext.GetCollection<TDocument>(partitionKey);
}
}
}
@@ -0,0 +1,531 @@
using MongoDB.Driver;
using MongoDbGenericRepository.DataAccess.Read;
using MongoDbGenericRepository.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace MongoDbGenericRepository
{
/// <summary>
/// The base Repository, it is meant to be inherited from by your custom custom MongoRepository implementation.
/// Its constructor must be given a connection string and a database name.
/// </summary>
public abstract partial class ReadOnlyMongoRepository<TKey> : IReadOnlyMongoRepository<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// The connection string.
/// </summary>
public string ConnectionString { get; protected set; }
/// <summary>
/// The database name.
/// </summary>
public string DatabaseName { get; protected set; }
/// <summary>
/// The MongoDbContext
/// </summary>
protected IMongoDbContext MongoDbContext = null;
/// <summary>
/// A MongoDb Reader for read operations
/// </summary>
protected MongoDbReader MongoDbReader = null;
/// <summary>
/// The constructor taking a connection string and a database name.
/// </summary>
/// <param name="connectionString">The connection string of the MongoDb server.</param>
/// <param name="databaseName">The name of the database against which you want to perform operations.</param>
protected ReadOnlyMongoRepository(string connectionString, string databaseName = null)
{
SetupMongoDbContext(connectionString, databaseName);
}
/// <summary>
/// The contructor taking a <see cref="IMongoDatabase"/>.
/// </summary>
/// <param name="mongoDatabase">A mongodb context implementing <see cref="IMongoDatabase"/></param>
protected ReadOnlyMongoRepository(IMongoDatabase mongoDatabase) : this(new MongoDbContext(mongoDatabase))
{
}
/// <summary>
/// The contructor taking a <see cref="IMongoDbContext"/>.
/// </summary>
/// <param name="mongoDbContext">A mongodb context implementing <see cref="IMongoDbContext"/></param>
protected ReadOnlyMongoRepository(IMongoDbContext mongoDbContext)
{
SetupMongoDbContext(mongoDbContext);
}
protected void SetupMongoDbContext(IMongoDbContext mongoDbContext)
{
MongoDbContext = MongoDbContext ?? mongoDbContext;
MongoDbReader = MongoDbReader ?? new MongoDbReader(MongoDbContext);
}
protected void SetupMongoDbContext(string connectionString, string databaseName)
{
if (databaseName == null)
{
var mongoUrl = new MongoUrl(connectionString);
databaseName = databaseName ?? mongoUrl.DatabaseName;
}
ConnectionString = connectionString;
DatabaseName = databaseName;
SetupMongoDbContext(new MongoDbContext(connectionString, databaseName));
}
#region Read
/// <summary>
/// Asynchronously returns one document given its id.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="id">The Id of the document you want to get.</param>
/// <param name="partitionKey">An optional partition key.</param>
public async Task<TDocument> GetByIdAsync<TDocument>(TKey id, string partitionKey = null) where TDocument : IDocument<TKey>
{
return await MongoDbReader.GetByIdAsync<TDocument, TKey>(id, partitionKey);
}
/// <summary>
/// Returns one document given its id.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="id">The Id of the document you want to get.</param>
/// <param name="partitionKey">An optional partition key.</param>
public TDocument GetById<TDocument>(TKey id, string partitionKey = null) where TDocument : IDocument<TKey>
{
return MongoDbReader.GetById<TDocument, TKey>(id, partitionKey);
}
/// <summary>
/// Asynchronously returns one document given an expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
public async Task<TDocument> GetOneAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>
{
return await MongoDbReader.GetOneAsync<TDocument, TKey>(filter, partitionKey);
}
/// <summary>
/// Returns one document given an expression filter.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
public TDocument GetOne<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>
{
return MongoDbReader.GetOne<TDocument, TKey>(filter, partitionKey);
}
/// <summary>
/// Returns a collection cursor.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
public IFindFluent<TDocument, TDocument> GetCursor<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>
{
return MongoDbReader.GetCursor<TDocument, TKey>(filter, partitionKey);
}
/// <summary>
/// Returns true if any of the document of the collection matches the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
public async Task<bool> AnyAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>
{
return await MongoDbReader.AnyAsync<TDocument, TKey>(filter, partitionKey);
}
/// <summary>
/// Returns true if any of the document of the collection matches the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
public bool Any<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>
{
return MongoDbReader.Any<TDocument, TKey>(filter, partitionKey);
}
/// <summary>
/// Asynchronously returns a list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
public async Task<List<TDocument>> GetAllAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>
{
return await MongoDbReader.GetAllAsync<TDocument, TKey>(filter, partitionKey);
}
/// <summary>
/// Returns a list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partition key.</param>
public List<TDocument> GetAll<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>
{
return MongoDbReader.GetAll<TDocument, TKey>(filter, partitionKey);
}
/// <summary>
/// Asynchronously counts how many documents match the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partitionKey</param>
public async Task<long> CountAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>
{
return await MongoDbReader.CountAsync<TDocument, TKey>(filter, partitionKey);
}
/// <summary>
/// Counts how many documents match the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="partitionKey">An optional partitionKey</param>
public long Count<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument<TKey>
{
return MongoDbReader.Count<TDocument, TKey>(filter, partitionKey);
}
/// <summary>
/// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="maxValueSelector">A property selector to order by descending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
public async Task<TDocument> GetByMaxAsync<TDocument>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, object>> maxValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbReader.GetByMaxAsync<TDocument, TKey>(filter, maxValueSelector, partitionKey);
}
/// <summary>
/// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="maxValueSelector">A property selector to order by descending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
/// <returns></returns>
public TDocument GetByMax<TDocument>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, object>> maxValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return MongoDbReader.GetByMax<TDocument, TKey>(filter, maxValueSelector, partitionKey);
}
/// <summary>
/// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
public async Task<TDocument> GetByMinAsync<TDocument>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, object>> minValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbReader.GetByMinAsync<TDocument, TKey>(filter, minValueSelector, partitionKey);
}
/// <summary>
/// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
public TDocument GetByMin<TDocument>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, object>> minValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return MongoDbReader.GetByMin<TDocument, TKey>(filter, minValueSelector, partitionKey);
}
/// <summary>
/// Gets the maximum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="maxValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
public async Task<TValue> GetMaxValueAsync<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> maxValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbReader.GetMaxValueAsync<TDocument, TKey, TValue>(filter, maxValueSelector, partitionKey);
}
/// <summary>
/// Gets the maximum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="maxValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partitionKey.</param>
public TValue GetMaxValue<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> maxValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return MongoDbReader.GetMaxValue<TDocument, TKey, TValue>(filter, maxValueSelector, partitionKey);
}
/// <summary>
/// Gets the minimum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual async Task<TValue> GetMinValueAsync<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbReader.GetMinValueAsync<TDocument, TKey, TValue>(filter, minValueSelector, partitionKey);
}
/// <summary>
/// Gets the minimum value of a property in a mongodb collections that is satisfying the filter.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <typeparam name="TValue">The type of the value used to order the query.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="minValueSelector">A property selector to order by ascending.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual TValue GetMinValue<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return MongoDbReader.GetMinValue<TDocument, TKey, TValue>(filter, minValueSelector, partitionKey);
}
#endregion
#region Maths
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
public virtual async Task<int> SumByAsync<TDocument>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, int>> selector,
string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbReader.SumByAsync<TDocument, TKey>(filter, selector, partitionKey);
}
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
public virtual async Task<decimal> SumByAsync<TDocument>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, decimal>> selector,
string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbReader.SumByAsync<TDocument, TKey>(filter, selector, partitionKey);
}
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
public virtual int SumBy<TDocument>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, int>> selector,
string partitionKey = null)
where TDocument : IDocument<TKey>
{
return MongoDbReader.SumBy<TDocument, TKey>(filter, selector, partitionKey);
}
/// <summary>
/// Sums the values of a selected field for a given filtered collection of documents.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="selector">The field you want to sum.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
public virtual decimal SumBy<TDocument>(Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, decimal>> selector,
string partitionKey = null)
where TDocument : IDocument<TKey>
{
return MongoDbReader.SumBy<TDocument, TKey>(filter, selector, partitionKey);
}
#endregion Maths
#region Project
/// <summary>
/// Asynchronously returns a projected document matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TKey">The type of the primary key for a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual async Task<TProjection> ProjectOneAsync<TDocument, TProjection>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
where TDocument : IDocument<TKey>
where TProjection : class
{
return await MongoDbReader.ProjectOneAsync<TDocument, TProjection, TKey>(filter, projection, partitionKey);
}
/// <summary>
/// Returns a projected document matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual TProjection ProjectOne<TDocument, TProjection>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
where TDocument : IDocument<TKey>
where TProjection : class
{
return MongoDbReader.ProjectOne<TDocument, TProjection, TKey>(filter, projection, partitionKey);
}
/// <summary>
/// Asynchronously returns a list of projected documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual async Task<List<TProjection>> ProjectManyAsync<TDocument, TProjection>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
where TDocument : IDocument<TKey>
where TProjection : class
{
return await MongoDbReader.ProjectManyAsync<TDocument, TProjection, TKey>(filter, projection, partitionKey);
}
/// <summary>
/// Asynchronously returns a list of projected documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TProjection">The type representing the model you want to project to.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="projection">The projection expression.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual List<TProjection> ProjectMany<TDocument, TProjection>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
where TDocument : IDocument<TKey>
where TProjection : class
{
return MongoDbReader.ProjectMany<TDocument, TProjection, TKey>(filter, projection, partitionKey);
}
#endregion Project
/// <summary>
/// Groups a collection of documents given a grouping criteria,
/// and returns a dictionary of listed document groups with keys having the different values of the grouping criteria.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TGroupKey">The type of the grouping criteria.</typeparam>
/// <typeparam name="TProjection">The type of the projected group.</typeparam>
/// <param name="groupingCriteria">The grouping criteria.</param>
/// <param name="groupProjection">The projected group result.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
public virtual List<TProjection> GroupBy<TDocument, TGroupKey, TProjection>(
Expression<Func<TDocument, TGroupKey>> groupingCriteria,
Expression<Func<IGrouping<TGroupKey, TDocument>, TProjection>> groupProjection,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TProjection : class, new()
{
return MongoDbReader.GroupBy<TDocument, TGroupKey, TProjection, TKey>(groupingCriteria, groupProjection, partitionKey);
}
/// <summary>
/// Groups filtered a collection of documents given a grouping criteria,
/// and returns a dictionary of listed document groups with keys having the different values of the grouping criteria.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TGroupKey">The type of the grouping criteria.</typeparam>
/// <typeparam name="TProjection">The type of the projected group.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="groupingCriteria">The grouping criteria.</param>
/// <param name="groupProjection">The projected group result.</param>
/// <param name="partitionKey">The partition key of your document, if any.</param>
public virtual List<TProjection> GroupBy<TDocument, TGroupKey, TProjection>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, TGroupKey>> groupingCriteria,
Expression<Func<IGrouping<TGroupKey, TDocument>, TProjection>> groupProjection,
string partitionKey = null)
where TDocument : IDocument<TKey>
where TProjection : class, new()
{
return MongoDbReader.GroupBy<TDocument, TGroupKey, TProjection, TKey>(filter, groupingCriteria, groupProjection, partitionKey);
}
/// <summary>
/// Asynchronously returns a paginated list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="sortSelector">The property selector.</param>
/// <param name="ascending">Order of the sorting.</param>
/// <param name="skipNumber">The number of documents you want to skip. Default value is 0.</param>
/// <param name="takeNumber">The number of documents you want to take. Default value is 50.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual async Task<List<TDocument>> GetSortedPaginatedAsync<TDocument>(
Expression<Func<TDocument, bool>> filter,
Expression<Func<TDocument, object>> sortSelector,
bool ascending = true,
int skipNumber = 0,
int takeNumber = 50,
string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbReader.GetSortedPaginatedAsync<TDocument, TKey>(filter, sortSelector, ascending, skipNumber, takeNumber, partitionKey);
}
/// <summary>
/// Asynchronously returns a paginated list of the documents matching the filter condition.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">A LINQ expression filter.</param>
/// <param name="sortDefinition">The sort definition.</param>
/// <param name="skipNumber">The number of documents you want to skip. Default value is 0.</param>
/// <param name="takeNumber">The number of documents you want to take. Default value is 50.</param>
/// <param name="partitionKey">An optional partition key.</param>
public virtual async Task<List<TDocument>> GetSortedPaginatedAsync<TDocument>(
Expression<Func<TDocument, bool>> filter,
SortDefinition<TDocument> sortDefinition,
int skipNumber = 0,
int takeNumber = 50,
string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbReader.GetSortedPaginatedAsync<TDocument, TKey>(filter, sortDefinition, skipNumber, takeNumber, partitionKey);
}
}
}
@@ -0,0 +1,469 @@
using MongoDB.Driver;
using MongoDbGenericRepository.DataAccess.Update;
using MongoDbGenericRepository.Models;
using System;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace MongoDbGenericRepository
{
public interface IBaseMongoRepository_Update<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// Asynchronously Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
Task<bool> UpdateOneAsync<TDocument>(TDocument modifiedDocument) where TDocument : IDocument<TKey>;
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
bool UpdateOne<TDocument>(TDocument modifiedDocument) where TDocument : IDocument<TKey>;
/// <summary>
/// Takes a document you want to modify and applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="update">The update definition for the document.</param>
Task<bool> UpdateOneAsync<TDocument>(TDocument documentToModify, UpdateDefinition<TDocument> update)
where TDocument : IDocument<TKey>;
/// <summary>
/// Takes a document you want to modify and applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="update">The update definition for the document.</param>
bool UpdateOne<TDocument>(TDocument documentToModify, UpdateDefinition<TDocument> update)
where TDocument : IDocument<TKey>;
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
bool UpdateOne<TDocument, TField>(TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value)
where TDocument : IDocument<TKey>;
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
Task<bool> UpdateOneAsync<TDocument, TField>(TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value)
where TDocument : IDocument<TKey>;
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
bool UpdateOne<TDocument, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// For the entity selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
bool UpdateOne<TDocument, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
Task<bool> UpdateOneAsync<TDocument, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// For the entity selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
Task<bool> UpdateOneAsync<TDocument, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
Task<long> UpdateManyAsync<TDocument, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
Task<long> UpdateManyAsync<TDocument, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
Task<long> UpdateManyAsync<TDocument>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
Task<long> UpdateManyAsync<TDocument>(Expression<Func<TDocument, bool>> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
long UpdateMany<TDocument, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
long UpdateMany<TDocument, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
long UpdateMany<TDocument>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>;
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
long UpdateMany<TDocument>(Expression<Func<TDocument, bool>> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>;
}
public abstract partial class BaseMongoRepository<TKey> : IBaseMongoRepository_Update<TKey>
where TKey : IEquatable<TKey>
{
private MongoDbUpdater _mongoDbUpdater;
protected virtual MongoDbUpdater MongoDbUpdater
{
get
{
if (_mongoDbUpdater != null) { return _mongoDbUpdater; }
lock (_initLock)
{
if (_mongoDbUpdater == null)
{
_mongoDbUpdater = new MongoDbUpdater(MongoDbContext);
}
}
return _mongoDbUpdater;
}
set { _mongoDbUpdater = value; }
}
/// <summary>
/// Asynchronously Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument>(TDocument modifiedDocument) where TDocument : IDocument<TKey>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, TKey>(modifiedDocument);
}
/// <summary>
/// Updates a document.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
public virtual bool UpdateOne<TDocument>(TDocument modifiedDocument) where TDocument : IDocument<TKey>
{
return MongoDbUpdater.UpdateOne<TDocument, TKey>(modifiedDocument);
}
/// <summary>
/// Takes a document you want to modify and applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="update">The update definition for the document.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument>(TDocument documentToModify, UpdateDefinition<TDocument> update)
where TDocument : IDocument<TKey>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, TKey>(documentToModify, update);
}
/// <summary>
/// Takes a document you want to modify and applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="update">The update definition for the document.</param>
public virtual bool UpdateOne<TDocument>(TDocument documentToModify, UpdateDefinition<TDocument> update)
where TDocument : IDocument<TKey>
{
return MongoDbUpdater.UpdateOne<TDocument, TKey>(documentToModify, update);
}
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
public virtual bool UpdateOne<TDocument, TField>(TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value)
where TDocument : IDocument<TKey>
{
return MongoDbUpdater.UpdateOne<TDocument, TKey, TField>(documentToModify, field, value);
}
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="documentToModify">The document you want to modify.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TField>(TDocument documentToModify, Expression<Func<TDocument, TField>> field, TField value)
where TDocument : IDocument<TKey>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, TKey, TField>(documentToModify, field, value);
}
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual bool UpdateOne<TDocument, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return MongoDbUpdater.UpdateOne<TDocument, TKey, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entity selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
public virtual bool UpdateOne<TDocument, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return MongoDbUpdater.UpdateOne<TDocument, TKey, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// Updates the property field with the given value update a property field in entities.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, TKey, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entity selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
public virtual async Task<bool> UpdateOneAsync<TDocument, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbUpdater.UpdateOneAsync<TDocument, TKey, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
public virtual async Task<long> UpdateManyAsync<TDocument, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbUpdater.UpdateManyAsync<TDocument, TKey, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<long> UpdateManyAsync<TDocument, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbUpdater.UpdateManyAsync<TDocument, TKey, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<long> UpdateManyAsync<TDocument>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbUpdater.UpdateManyAsync<TDocument, TKey>(filter, updateDefinition, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual async Task<long> UpdateManyAsync<TDocument>(Expression<Func<TDocument, bool>> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return await MongoDbUpdater.UpdateManyAsync<TDocument, TKey>(filter, updateDefinition, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The partition key for the document.</param>
public virtual long UpdateMany<TDocument, TField>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return MongoDbUpdater.UpdateMany<TDocument, TKey, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, updates the property field with the given value.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <typeparam name="TField">The type of the field.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="field">The field selector.</param>
/// <param name="value">The new value of the property field.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual long UpdateMany<TDocument, TField>(FilterDefinition<TDocument> filter, Expression<Func<TDocument, TField>> field, TField value, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return MongoDbUpdater.UpdateMany<TDocument, TKey, TField>(filter, field, value, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual long UpdateMany<TDocument>(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null)
where TDocument : IDocument<TKey>
{
return MongoDbUpdater.UpdateMany<TDocument, TKey>(filter, updateDefinition, partitionKey);
}
/// <summary>
/// For the entities selected by the filter, applies the update you have defined in MongoDb.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="filter">The document filter.</param>
/// <param name="updateDefinition">The update definition to apply.</param>
/// <param name="partitionKey">The value of the partition key.</param>
public virtual long UpdateMany<TDocument>(Expression<Func<TDocument, bool>> filter, UpdateDefinition<TDocument> updateDefinition, string partitionKey = null) where TDocument : IDocument<TKey>
{
return MongoDbUpdater.UpdateMany<TDocument, TKey>(filter, updateDefinition, partitionKey);
}
}
}

Some files were not shown because too many files have changed in this diff Show More