Compare commits
116 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eebdc89575 | |||
| ee4950c5d4 | |||
| 658c753989 | |||
| 0e8d629a8f | |||
| ba3f876f95 | |||
| e4a36e5c60 | |||
| 592c30ed2c | |||
| 83f1d2c7a6 | |||
| ab294d1a5d | |||
| dd8cbe3da7 | |||
| 0844c51566 | |||
| 601c0fd02d | |||
| 91d15312e6 | |||
| 54b2a63a8e | |||
| dbb27aad39 | |||
| afd0308849 | |||
| 9cb35c5881 | |||
| c5390214eb | |||
| ac1fd709a6 | |||
| f6b0aa274b | |||
| 7a82a281fb | |||
| dca01b184c | |||
| b1cda2ac50 | |||
| 8d6b796e7f | |||
| 1a7763a312 | |||
| 77cc85574c | |||
| 846bb16730 | |||
| 5e4cbfa1b3 | |||
| 804dc18c4f | |||
| 182ee0a335 | |||
| bd662d25d6 | |||
| 6c8d4bdafb | |||
| 4d94a1b436 | |||
| d91a644b4a | |||
| 9d1950e9c7 | |||
| 67d0a4c8a3 | |||
| 1826668cea | |||
| b855677efd | |||
| 530309e9fc | |||
| 69ad94e4a3 | |||
| baaf2b5ee9 | |||
| d2df667b3f | |||
| 8ccced66ea | |||
| c92a126ecc | |||
| 2207f2f1a1 | |||
| 0626292d09 | |||
| 29f01d2dab | |||
| a7391e06f8 | |||
| 43677b72a1 | |||
| 2f29efafe3 | |||
| d2f465b063 | |||
| 75b894cb2a | |||
| ba723be738 | |||
| f773e599d0 | |||
| 17653b05f7 | |||
| 69903fd69b | |||
| 9edd7e97fe | |||
| b77978e57a | |||
| 648b57612d | |||
| 4ac0ffe91c | |||
| eaa90d67f5 | |||
| 2d866d966c | |||
| ffc7e65b7b | |||
| 0cf24b1dcf | |||
| fd8f98e375 | |||
| fa6687c084 | |||
| 0b939592ba | |||
| ad18170804 | |||
| 099e16a88c | |||
| e41a73f745 | |||
| 526adf0a23 | |||
| db4061dc3c | |||
| 72ea6e7999 | |||
| 7f126a098d | |||
| 456af09a84 | |||
| f0af32adca | |||
| 345fca2e6e | |||
| 57d332ef2a | |||
| 2f6515a809 | |||
| 82dc2f2024 | |||
| bc992e8c61 | |||
| 47e85f1760 | |||
| 6f5eb71dad | |||
| ed0d206a97 | |||
| 40ff874cf6 | |||
| 9fc74fc28e | |||
| 5270271008 | |||
| bf2119432e | |||
| e581586161 | |||
| 1a83abd25f | |||
| 03b0e4265b | |||
| c117bf2a7f | |||
| c50e4d086e | |||
| 3a42a1c574 | |||
| 67e7318021 | |||
| 29012d1e52 | |||
| e15c1e4ad2 | |||
| 3d104764ae | |||
| 3af68c06db | |||
| a3ae98d077 | |||
| aff276f9e3 | |||
| e91c89f054 | |||
| 657beeac99 | |||
| fbb07475a1 | |||
| 30ea910b9c | |||
| aae71cddc3 | |||
| ad2cd66a7d | |||
| bfe1652b9c | |||
| 9c0cd0fe47 | |||
| c07b1a5d7b | |||
| 76862b2caa | |||
| a13800637f | |||
| 1d985e0274 | |||
| 833263edbf | |||
| 6552a01d28 | |||
| 9b1048e318 |
@@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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,19 +1,32 @@
|
|||||||
<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="MongoDbGenericRepository" Version="1.2.1" />
|
<PackageReference Include="MongoDB.Driver" Version="2.12.0" />
|
||||||
<PackageReference Include="xunit" Version="2.3.0-beta5-build3769" />
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
<PackageReference Include="xunit.runner.console" Version="2.3.0-beta5-build3769" />
|
<PackageReference Include="xunit.runner.console" Version="2.4.1">
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta5-build3769" />
|
<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>
|
||||||
|
<ProjectReference Include="..\MongoDbGenericRepository\MongoDbGenericRepository.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System.Configuration">
|
||||||
|
<HintPath>..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Configuration.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="App.config">
|
<None Update="App.config">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,4 +7,12 @@
|
|||||||
<connectionStrings>
|
<connectionStrings>
|
||||||
<add name="MongoDbTests" connectionString="mongodb://localhost:27017" />
|
<add name="MongoDbTests" connectionString="mongodb://localhost:27017" />
|
||||||
</connectionStrings>
|
</connectionStrings>
|
||||||
|
<runtime>
|
||||||
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
</assemblyBinding>
|
||||||
|
</runtime>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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,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,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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,7 @@ using System.Configuration;
|
|||||||
|
|
||||||
namespace IntegrationTests.Infrastructure
|
namespace IntegrationTests.Infrastructure
|
||||||
{
|
{
|
||||||
public class BaseMongoDbRepositoryTests<T> where T : Document, new()
|
public class BaseMongoDbRepositoryTests<T> where T : class, new()
|
||||||
{
|
{
|
||||||
public T CreateTestDocument()
|
public T CreateTestDocument()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,44 +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\MongoDbGenericRepository.1.2.1\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\MongoDbGenericRepository.1.2.1\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\MongoDbGenericRepository.1.2.1\lib\net45\MongoDB.Driver.Core.dll</HintPath>
|
<HintPath>..\packages\MongoDB.Bson.2.9.3\lib\net452\MongoDB.Bson.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="MongoDbGenericRepository, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="MongoDB.Driver, Version=2.9.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\MongoDbGenericRepository.1.2.1\lib\net45\MongoDbGenericRepository.dll</HintPath>
|
<HintPath>..\packages\MongoDB.Driver.2.9.3\lib\net452\MongoDB.Driver.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="nunit.framework, Version=3.7.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
<Reference Include="MongoDB.Driver.Core, 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.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.0.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\MongoDbGenericRepository.1.2.1\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>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="DeletePartitionedTests.cs" />
|
<Compile Include="CRUDObjectIdTests.cs" />
|
||||||
<Compile Include="DeleteTests.cs" />
|
<Compile Include="CRUDPartitionedTests.cs" />
|
||||||
|
<Compile Include="CRUDTKeyPartitionedCollectionNameAttributeTests.cs" />
|
||||||
|
<Compile Include="CRUDTests.cs" />
|
||||||
|
<Compile Include="CRUDPartitionedCollectionNameAttributeTests.cs" />
|
||||||
|
<Compile Include="CRUDTKeyPartitionedTests.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\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="ProjectPartitionedTests.cs" />
|
|
||||||
<Compile Include="ProjectTests.cs" />
|
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="ReadPartitionedTests.cs" />
|
|
||||||
<Compile Include="ReadTests.cs" />
|
|
||||||
<Compile Include="UpdatePartitionedTests.cs" />
|
|
||||||
<Compile Include="UpdateTests.cs" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="App.config">
|
<None Include="App.config">
|
||||||
@@ -79,4 +102,10 @@
|
|||||||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
||||||
</ItemGroup>
|
</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,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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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,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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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,51 +0,0 @@
|
|||||||
using IntegrationTests.Infrastructure;
|
|
||||||
using MongoDbGenericRepository.Models;
|
|
||||||
using NUnit.Framework;
|
|
||||||
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>
|
|
||||||
{
|
|
||||||
[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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
using IntegrationTests.Infrastructure;
|
|
||||||
using MongoDbGenericRepository.Models;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace IntegrationTests
|
|
||||||
{
|
|
||||||
public class UpdateTestsDocument : Document
|
|
||||||
{
|
|
||||||
public UpdateTestsDocument()
|
|
||||||
{
|
|
||||||
Version = 2;
|
|
||||||
}
|
|
||||||
public string SomeContent { 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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="MongoDbGenericRepository" version="1.2.1" targetFramework="net461" />
|
<package id="MongoDB.Driver" version="2.9.3" targetFramework="net461" />
|
||||||
<package id="NUnit" version="3.7.1" targetFramework="net461" />
|
<package id="MongoDB.Driver.Core" version="2.9.3" targetFramework="net461" />
|
||||||
<package id="NUnit.ConsoleRunner" version="3.7.0" targetFramework="net461" />
|
<package id="MongoDbGenericRepository" version="1.4.5" targetFramework="net461" />
|
||||||
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.0.0" 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" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
-14
@@ -1,5 +1,6 @@
|
|||||||
using MongoDB.Driver;
|
using MongoDB.Driver;
|
||||||
using MongoDbGenericRepository.Models;
|
using MongoDbGenericRepository.Models;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace MongoDbGenericRepository
|
namespace MongoDbGenericRepository
|
||||||
{
|
{
|
||||||
@@ -18,29 +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>
|
|
||||||
/// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,808 +0,0 @@
|
|||||||
using MongoDB.Driver;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using MongoDbGenericRepository.Models;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace MongoDbGenericRepository
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The IBaseMongoRepository exposes the functionality of the BaseMongoRepository.
|
|
||||||
/// </summary>
|
|
||||||
public interface IBaseMongoRepository
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The connection string.
|
|
||||||
/// </summary>
|
|
||||||
string ConnectionString { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// The database name.
|
|
||||||
/// </summary>
|
|
||||||
string DatabaseName { get; set; }
|
|
||||||
|
|
||||||
#region Create
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously adds a document to the collection.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="document">The document you want to add.</param>
|
|
||||||
Task AddOneAsync<TDocument>(TDocument document) where TDocument : IDocument;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a document to the collection.
|
|
||||||
/// Populates the Id and AddedAtUtc fields if necessary.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="document">The document you want to add.</param>
|
|
||||||
void AddOne<TDocument>(TDocument document) where TDocument : IDocument;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously adds a list of documents to the collection.
|
|
||||||
/// Populates the Id and AddedAtUtc fields if necessary.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="documents">The document you want to add.</param>
|
|
||||||
Task AddManyAsync<TDocument>(IEnumerable<TDocument> documents) where TDocument : IDocument;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a list of documents to the collection.
|
|
||||||
/// Populates the Id and AddedAtUtc fields if necessary.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="documents">The document you want to add.</param>
|
|
||||||
void AddMany<TDocument>(IEnumerable<TDocument> documents) where TDocument : IDocument;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Read
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously returns one document given its id.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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>(Guid id, string partitionKey = null) where TDocument : IDocument;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns one document given its id.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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>(Guid id, string partitionKey = null) where TDocument : IDocument;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously returns one document given an expression filter.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns one document given an expression filter.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a collection cursor.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously returns true if any of the document of the collection matches the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if any of the document of the collection matches the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously returns a list of the documents matching the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a list of the documents matching the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously counts how many documents match the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Counts how many documents match the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Update
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously Updates a document.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
|
|
||||||
Task<bool> UpdateOneAsync<TDocument>(TDocument modifiedDocument) where TDocument : IDocument;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates a document.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
|
|
||||||
bool UpdateOne<TDocument>(TDocument modifiedDocument) where TDocument : IDocument;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Delete
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously deletes a document.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously deletes a document matching the condition of the LINQ expression filter.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes a document.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes a document matching the condition of the LINQ expression filter.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously deletes the documents matching the condition of the LINQ expression filter.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously deletes a list of documents.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes a list of documents.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes the documents matching the condition of the LINQ expression filter.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Project
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously returns a projected document matching the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <typeparam name="TProjection"></typeparam>
|
|
||||||
/// <param name="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
|
|
||||||
where TProjection : class;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a projected document matching the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <typeparam name="TProjection"></typeparam>
|
|
||||||
/// <param name="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
|
|
||||||
where TProjection : class;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously returns a list of projected documents matching the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <typeparam name="TProjection"></typeparam>
|
|
||||||
/// <param name="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
|
|
||||||
where TProjection : class;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously returns a list of projected documents matching the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <typeparam name="TProjection"></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>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
|
|
||||||
where TDocument : IDocument
|
|
||||||
where TProjection : class;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <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 class BaseMongoRepository : IBaseMongoRepository
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The connection string.
|
|
||||||
/// </summary>
|
|
||||||
public string ConnectionString { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// The database name.
|
|
||||||
/// </summary>
|
|
||||||
public string DatabaseName { get; set; }
|
|
||||||
|
|
||||||
/// <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)
|
|
||||||
{
|
|
||||||
MongoDbContext = new MongoDbContext(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)
|
|
||||||
{
|
|
||||||
MongoDbContext = mongoDbContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The MongoDbContext
|
|
||||||
/// </summary>
|
|
||||||
protected IMongoDbContext MongoDbContext = null;
|
|
||||||
|
|
||||||
#region Create
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously adds a document to the collection.
|
|
||||||
/// Populates the Id and AddedAtUtc fields if necessary.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="document">The document you want to add.</param>
|
|
||||||
public async Task AddOneAsync<TDocument>(TDocument document) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
FormatDocument(document);
|
|
||||||
await HandlePartitioned(document).InsertOneAsync(document);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a document to the collection.
|
|
||||||
/// Populates the Id and AddedAtUtc fields if necessary.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="document">The document you want to add.</param>
|
|
||||||
public void AddOne<TDocument>(TDocument document) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
FormatDocument(document);
|
|
||||||
HandlePartitioned(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"></typeparam>
|
|
||||||
/// <param name="documents">The documents you want to add.</param>
|
|
||||||
public async Task AddManyAsync<TDocument>(IEnumerable<TDocument> documents) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
if (!documents.Any())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
foreach (var doc in documents)
|
|
||||||
{
|
|
||||||
FormatDocument(doc);
|
|
||||||
}
|
|
||||||
await HandlePartitioned(documents.FirstOrDefault()).InsertManyAsync(documents);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a list of documents to the collection.
|
|
||||||
/// Populates the Id and AddedAtUtc fields if necessary.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="documents">The documents you want to add.</param>
|
|
||||||
public void AddMany<TDocument>(IEnumerable<TDocument> documents) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
if (!documents.Any())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
foreach (var document in documents)
|
|
||||||
{
|
|
||||||
FormatDocument(document);
|
|
||||||
}
|
|
||||||
HandlePartitioned(documents.FirstOrDefault()).InsertMany(documents.ToList());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Create
|
|
||||||
|
|
||||||
#region Read
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously returns one document given its id.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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>(Guid id, string partitionKey = null) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
var filter = Builders<TDocument>.Filter.Eq("Id", id);
|
|
||||||
return await HandlePartitioned<TDocument>(partitionKey).Find(filter).FirstOrDefaultAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns one document given its id.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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>(Guid id, string partitionKey = null) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
var filter = Builders<TDocument>.Filter.Eq("Id", id);
|
|
||||||
return HandlePartitioned<TDocument>(partitionKey).Find(filter).FirstOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously returns one document given an expression filter.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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
|
|
||||||
{
|
|
||||||
return await HandlePartitioned<TDocument>(partitionKey).Find(filter).FirstOrDefaultAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns one document given an expression filter.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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
|
|
||||||
{
|
|
||||||
return HandlePartitioned<TDocument>(partitionKey).Find(filter).FirstOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a collection cursor.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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
|
|
||||||
{
|
|
||||||
return HandlePartitioned<TDocument>(partitionKey).Find(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if any of the document of the collection matches the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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
|
|
||||||
{
|
|
||||||
var count = await HandlePartitioned<TDocument>(partitionKey).CountAsync(filter);
|
|
||||||
return (count > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if any of the document of the collection matches the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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
|
|
||||||
{
|
|
||||||
var count = HandlePartitioned<TDocument>(partitionKey).Count(filter);
|
|
||||||
return (count > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously returns a list of the documents matching the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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
|
|
||||||
{
|
|
||||||
return await HandlePartitioned<TDocument>(partitionKey).Find(filter).ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a list of the documents matching the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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
|
|
||||||
{
|
|
||||||
return HandlePartitioned<TDocument>(partitionKey).Find(filter).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously counts how many documents match the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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
|
|
||||||
{
|
|
||||||
return await HandlePartitioned<TDocument>(partitionKey).CountAsync(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Counts how many documents match the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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
|
|
||||||
{
|
|
||||||
return HandlePartitioned<TDocument>(partitionKey).Find(filter).Count();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Update
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously Updates a document.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
|
|
||||||
public async Task<bool> UpdateOneAsync<TDocument>(TDocument modifiedDocument) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
var updateRes = await HandlePartitioned(modifiedDocument).ReplaceOneAsync(x => x.Id == modifiedDocument.Id, modifiedDocument);
|
|
||||||
return updateRes.ModifiedCount == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates a document.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="modifiedDocument">The document with the modifications you want to persist.</param>
|
|
||||||
public bool UpdateOne<TDocument>(TDocument modifiedDocument) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
var updateRes = HandlePartitioned(modifiedDocument).ReplaceOne(x => x.Id == modifiedDocument.Id, modifiedDocument);
|
|
||||||
return updateRes.ModifiedCount == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Update
|
|
||||||
|
|
||||||
#region Delete
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously deletes a document.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="document">The document you want to delete.</param>
|
|
||||||
/// <returns>The number of documents deleted.</returns>
|
|
||||||
public async Task<long> DeleteOneAsync<TDocument>(TDocument document) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
return (await HandlePartitioned(document).DeleteOneAsync(x => x.Id == document.Id)).DeletedCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes a document.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="document">The document you want to delete.</param>
|
|
||||||
/// <returns>The number of documents deleted.</returns>
|
|
||||||
public long DeleteOne<TDocument>(TDocument document) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
return HandlePartitioned(document).DeleteOne(x => x.Id == document.Id).DeletedCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes a document matching the condition of the LINQ expression filter.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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 long DeleteOne<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
return HandlePartitioned<TDocument>(partitionKey).DeleteOne(filter).DeletedCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously deletes a document matching the condition of the LINQ expression filter.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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 async Task<long> DeleteOneAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
return (await HandlePartitioned<TDocument>(partitionKey).DeleteOneAsync(filter)).DeletedCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously deletes the documents matching the condition of the LINQ expression filter.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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 async Task<long> DeleteManyAsync<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
return (await HandlePartitioned<TDocument>(partitionKey).DeleteManyAsync(filter)).DeletedCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously deletes a list of documents.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="documents">The list of documents to delete.</param>
|
|
||||||
/// <returns>The number of documents deleted.</returns>
|
|
||||||
public async Task<long> DeleteManyAsync<TDocument>(IEnumerable<TDocument> documents) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
if (!documents.Any())
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
var idsTodelete = documents.Select(e => e.Id).ToArray();
|
|
||||||
return (await HandlePartitioned(documents.FirstOrDefault()).DeleteManyAsync(x => idsTodelete.Contains(x.Id))).DeletedCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes a list of documents.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="documents">The list of documents to delete.</param>
|
|
||||||
/// <returns>The number of documents deleted.</returns>
|
|
||||||
public long DeleteMany<TDocument>(IEnumerable<TDocument> documents) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
if (!documents.Any())
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
var idsTodelete = documents.Select(e => e.Id).ToArray();
|
|
||||||
return HandlePartitioned(documents.FirstOrDefault()).DeleteMany(x => idsTodelete.Contains(x.Id)).DeletedCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes the documents matching the condition of the LINQ expression filter.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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 long DeleteMany<TDocument>(Expression<Func<TDocument, bool>> filter, string partitionKey = null) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
return HandlePartitioned<TDocument>(partitionKey).DeleteMany(filter).DeletedCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Delete
|
|
||||||
|
|
||||||
#region Project
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously returns a projected document matching the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <typeparam name="TProjection"></typeparam>
|
|
||||||
/// <param name="filter"></param>
|
|
||||||
/// <param name="projection">The projection expression.</param>
|
|
||||||
/// <param name="partitionKey">An optional partition key.</param>
|
|
||||||
public async Task<TProjection> ProjectOneAsync<TDocument, TProjection>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
|
|
||||||
where TDocument : IDocument
|
|
||||||
where TProjection : class
|
|
||||||
{
|
|
||||||
return await HandlePartitioned<TDocument>(partitionKey).Find(filter)
|
|
||||||
.Project(projection)
|
|
||||||
.FirstOrDefaultAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a projected document matching the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <typeparam name="TProjection"></typeparam>
|
|
||||||
/// <param name="filter"></param>
|
|
||||||
/// <param name="projection">The projection expression.</param>
|
|
||||||
/// <param name="partitionKey">An optional partition key.</param>
|
|
||||||
public TProjection ProjectOne<TDocument, TProjection>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
|
|
||||||
where TDocument : IDocument
|
|
||||||
where TProjection : class
|
|
||||||
{
|
|
||||||
return HandlePartitioned<TDocument>(partitionKey).Find(filter)
|
|
||||||
.Project(projection)
|
|
||||||
.FirstOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously returns a list of projected documents matching the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <typeparam name="TProjection"></typeparam>
|
|
||||||
/// <param name="filter"></param>
|
|
||||||
/// <param name="projection">The projection expression.</param>
|
|
||||||
/// <param name="partitionKey">An optional partition key.</param>
|
|
||||||
public async Task<List<TProjection>> ProjectManyAsync<TDocument, TProjection>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
|
|
||||||
where TDocument : IDocument
|
|
||||||
where TProjection : class
|
|
||||||
{
|
|
||||||
return await HandlePartitioned<TDocument>(partitionKey).Find(filter)
|
|
||||||
.Project(projection)
|
|
||||||
.ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously returns a list of projected documents matching the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <typeparam name="TProjection"></typeparam>
|
|
||||||
/// <param name="filter"></param>
|
|
||||||
/// <param name="projection">The projection expression.</param>
|
|
||||||
/// <param name="partitionKey">An optional partition key.</param>
|
|
||||||
public List<TProjection> ProjectMany<TDocument, TProjection>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TProjection>> projection, string partitionKey = null)
|
|
||||||
where TDocument : IDocument
|
|
||||||
where TProjection : class
|
|
||||||
{
|
|
||||||
return HandlePartitioned<TDocument>(partitionKey).Find(filter)
|
|
||||||
.Project(projection)
|
|
||||||
.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Asynchronously returns a paginated list of the documents matching the filter condition.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></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>
|
|
||||||
public 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Find And Update
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// GetAndUpdateOne with filter
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
|
||||||
/// <param name="filter"></param>
|
|
||||||
/// <param name="update"></param>
|
|
||||||
/// <param name="options"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Find And Update
|
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
|
|
||||||
private IMongoCollection<TDocument> GetCollection<TDocument>(string partitionKey) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
return MongoDbContext.GetCollection<TDocument>(partitionKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IMongoCollection<TDocument> GetCollection<TDocument>() where TDocument : IDocument
|
|
||||||
{
|
|
||||||
return MongoDbContext.GetCollection<TDocument>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private IMongoCollection<TDocument> HandlePartitioned<TDocument>(TDocument document) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
if (document is IPartitionedDocument)
|
|
||||||
{
|
|
||||||
return GetCollection<TDocument>(((IPartitionedDocument)document).PartitionKey);
|
|
||||||
}
|
|
||||||
return GetCollection<TDocument>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private IMongoCollection<TDocument> HandlePartitioned<TDocument>(string partitionKey) where TDocument : IDocument
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(partitionKey))
|
|
||||||
{
|
|
||||||
return GetCollection<TDocument>(partitionKey);
|
|
||||||
}
|
|
||||||
return GetCollection<TDocument>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
using MongoDbGenericRepository.DataAccess.Create;
|
||||||
|
using MongoDbGenericRepository.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MongoDbGenericRepository
|
||||||
|
{
|
||||||
|
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>
|
||||||
|
Task AddOneAsync<TDocument, TKey>(TDocument document)
|
||||||
|
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>
|
||||||
|
Task AddManyAsync<TDocument, TKey>(IEnumerable<TDocument> documents)
|
||||||
|
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;
|
||||||
|
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>
|
||||||
|
public virtual async Task AddOneAsync<TDocument, TKey>(TDocument document)
|
||||||
|
where TDocument : IDocument<TKey>
|
||||||
|
where TKey : IEquatable<TKey>
|
||||||
|
{
|
||||||
|
await MongoDbCreator.AddOneAsync<TDocument, TKey>(document);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
public virtual async Task AddOneAsync<TDocument>(TDocument document)
|
||||||
|
where TDocument : IDocument<Guid>
|
||||||
|
{
|
||||||
|
await MongoDbCreator.AddOneAsync<TDocument, Guid>(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>
|
||||||
|
/// <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>
|
||||||
|
public virtual async Task AddManyAsync<TDocument, TKey>(IEnumerable<TDocument> documents)
|
||||||
|
where TDocument : IDocument<TKey>
|
||||||
|
where TKey : IEquatable<TKey>
|
||||||
|
{
|
||||||
|
await MongoDbCreator.AddManyAsync<TDocument, TKey>(documents);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
public virtual async Task AddManyAsync<TDocument>(IEnumerable<TDocument> documents)
|
||||||
|
where TDocument : IDocument<Guid>
|
||||||
|
{
|
||||||
|
await MongoDbCreator.AddManyAsync<TDocument, Guid>(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>
|
||||||
|
/// <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,167 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
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,142 @@
|
|||||||
|
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.Tasks;
|
||||||
|
|
||||||
|
namespace MongoDbGenericRepository.DataAccess.Create
|
||||||
|
{
|
||||||
|
public class MongoDbCreator : DataAccessBase
|
||||||
|
{
|
||||||
|
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>
|
||||||
|
public virtual async Task AddOneAsync<TDocument, TKey>(TDocument document)
|
||||||
|
where TDocument : IDocument<TKey>
|
||||||
|
where TKey : IEquatable<TKey>
|
||||||
|
{
|
||||||
|
FormatDocument<TDocument, TKey>(document);
|
||||||
|
await HandlePartitioned<TDocument, TKey>(document).InsertOneAsync(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>
|
||||||
|
/// <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>
|
||||||
|
public virtual async Task AddManyAsync<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))
|
||||||
|
{
|
||||||
|
await HandlePartitioned<TDocument, TKey>(group.FirstOrDefault()).InsertManyAsync(group.ToList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await GetCollection<TDocument, TKey>().InsertManyAsync(documents.ToList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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,562 @@
|
|||||||
|
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
|
||||||
|
{
|
||||||
|
public partial class MongoDbReader : DataAccessBase
|
||||||
|
{
|
||||||
|
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,122 @@
|
|||||||
|
using MongoDbGenericRepository.DataAccess.Create;
|
||||||
|
using MongoDbGenericRepository.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
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>
|
||||||
|
Task AddOneAsync<TDocument>(TDocument document) 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>
|
||||||
|
Task AddManyAsync<TDocument>(IEnumerable<TDocument> documents) 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>
|
||||||
|
public virtual async Task AddOneAsync<TDocument>(TDocument document) where TDocument : IDocument<TKey>
|
||||||
|
{
|
||||||
|
await MongoDbCreator.AddOneAsync<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<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>
|
||||||
|
public virtual async Task AddManyAsync<TDocument>(IEnumerable<TDocument> documents) where TDocument : IDocument<TKey>
|
||||||
|
{
|
||||||
|
await MongoDbCreator.AddManyAsync<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<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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,16 +6,24 @@ namespace MongoDbGenericRepository.Models
|
|||||||
/// This class represents a basic document that can be stored in MongoDb.
|
/// This class represents a basic document that can be stored in MongoDb.
|
||||||
/// Your document must implement this class in order for the MongoDbRepository to handle them.
|
/// Your document must implement this class in order for the MongoDbRepository to handle them.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IDocument
|
public interface IDocument<TKey> where TKey : IEquatable<TKey>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Guid, which must be decorated with the [BsonId] attribute
|
/// The Primary Key, which must be decorated with the [BsonId] attribute
|
||||||
/// if you want the MongoDb C# driver to consider it to be the document ID.
|
/// if you want the MongoDb C# driver to consider it to be the document ID.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Guid Id { get; set; }
|
TKey Id { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A version number, to indicate the version of the schema.
|
/// A version number, to indicate the version of the schema.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
int Version { get; set; }
|
int Version { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents a basic document that can be stored in MongoDb.
|
||||||
|
/// Your document must implement this class in order for the MongoDbRepository to handle them.
|
||||||
|
/// </summary>
|
||||||
|
public interface IDocument : IDocument<Guid>
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
/// This can be useful if you are planning to build a Software as a Service (SaaS) Platform, or if you want to reduce indexing.
|
/// This can be useful if you are planning to build a Software as a Service (SaaS) Platform, or if you want to reduce indexing.
|
||||||
/// You could for example insert Logs in different collections based on the week and year they where created, or their Log category/source.
|
/// You could for example insert Logs in different collections based on the week and year they where created, or their Log category/source.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IPartitionedDocument : IDocument
|
public interface IPartitionedDocument
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The partition key used to partition your collection.
|
/// The partition key used to partition your collection.
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MongoDbGenericRepository.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Options for creating an index.
|
||||||
|
/// </summary>
|
||||||
|
public class IndexCreationOptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether the index is a unique index.
|
||||||
|
/// </summary>
|
||||||
|
public bool? Unique { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the index version for text indexes.
|
||||||
|
/// </summary>
|
||||||
|
public int? TextIndexVersion { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the index version for 2dsphere indexes.
|
||||||
|
/// </summary>
|
||||||
|
public int? SphereIndexVersion { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether the index is a sparse index.
|
||||||
|
/// </summary>
|
||||||
|
public bool? Sparse { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the index name.
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the min value for 2d indexes.
|
||||||
|
/// </summary>
|
||||||
|
public double? Min { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the max value for 2d indexes.
|
||||||
|
/// </summary>
|
||||||
|
public double? Max { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the language override.
|
||||||
|
/// </summary>
|
||||||
|
public string LanguageOverride { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets when documents expire (used with TTL indexes).
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan? ExpireAfter { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the default language.
|
||||||
|
/// </summary>
|
||||||
|
public string DefaultLanguage { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the precision, in bits, used with geohash indexes.
|
||||||
|
/// </summary>
|
||||||
|
public int? Bits { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether to create the index in the background.
|
||||||
|
/// </summary>
|
||||||
|
public bool? Background { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the version of the index.
|
||||||
|
/// </summary>
|
||||||
|
public int? Version { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
using MongoDB.Driver;
|
using MongoDB.Driver;
|
||||||
using MongoDbGenericRepository.Models;
|
using MongoDbGenericRepository.Attributes;
|
||||||
|
using MongoDbGenericRepository.Utils;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace MongoDbGenericRepository
|
namespace MongoDbGenericRepository
|
||||||
{
|
{
|
||||||
@@ -9,27 +12,24 @@ namespace MongoDbGenericRepository
|
|||||||
public class MongoDbContext : IMongoDbContext
|
public class MongoDbContext : IMongoDbContext
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The IMongoClient from the official MongoDb driver
|
/// The IMongoClient from the official MongoDB driver
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IMongoClient Client { get; }
|
public IMongoClient Client { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The IMongoDatabase from the official Mongodb driver
|
/// The IMongoDatabase from the official MongoDB driver
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IMongoDatabase Database { get; }
|
public IMongoDatabase Database { get; }
|
||||||
|
|
||||||
static MongoDbContext()
|
|
||||||
{
|
|
||||||
// Avoid legacy UUID representation: use Binary 0x04 subtype.
|
|
||||||
MongoDefaults.GuidRepresentation = MongoDB.Bson.GuidRepresentation.Standard;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The constructor of the MongoDbContext, it needs a an object implementing <see cref="IMongoDatabase"/>.
|
/// The constructor of the MongoDbContext, it needs an object implementing <see cref="IMongoDatabase"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="mongoDatabase">An object implementing IMongoDatabase</param>
|
/// <param name="mongoDatabase">An object implementing IMongoDatabase</param>
|
||||||
public MongoDbContext(IMongoDatabase mongoDatabase)
|
public MongoDbContext(IMongoDatabase mongoDatabase)
|
||||||
{
|
{
|
||||||
|
// Avoid legacy UUID representation: use Binary 0x04 subtype.
|
||||||
|
InitializeGuidRepresentation();
|
||||||
Database = mongoDatabase;
|
Database = mongoDatabase;
|
||||||
Client = Database.Client;
|
Client = Database.Client;
|
||||||
}
|
}
|
||||||
@@ -41,56 +41,106 @@ namespace MongoDbGenericRepository
|
|||||||
/// <param name="databaseName">The name of your database.</param>
|
/// <param name="databaseName">The name of your database.</param>
|
||||||
public MongoDbContext(string connectionString, string databaseName)
|
public MongoDbContext(string connectionString, string databaseName)
|
||||||
{
|
{
|
||||||
|
InitializeGuidRepresentation();
|
||||||
Client = new MongoClient(connectionString);
|
Client = new MongoClient(connectionString);
|
||||||
Database = Client.GetDatabase(databaseName);
|
Database = Client.GetDatabase(databaseName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The private GetCollection method
|
/// Initialise an instance of a <see cref="IMongoDbContext"/> using a connection string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
/// <param name="connectionString"></param>
|
||||||
/// <returns></returns>
|
public MongoDbContext(string connectionString)
|
||||||
public IMongoCollection<TDocument> GetCollection<TDocument>()
|
: this(connectionString, new MongoUrl(connectionString).DatabaseName)
|
||||||
{
|
{
|
||||||
return Database.GetCollection<TDocument>(Pluralize<TDocument>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a collection for a document type that has a partition key.
|
/// The constructor of the MongoDbContext, it needs a connection string and a database name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
/// <param name="client">The MongoClient.</param>
|
||||||
/// <param name="partitionKey">The value of the partition key.</param>
|
/// <param name="databaseName">The name of your database.</param>
|
||||||
public IMongoCollection<TDocument> GetCollection<TDocument>(string partitionKey) where TDocument : IDocument
|
public MongoDbContext(MongoClient client, string databaseName)
|
||||||
{
|
{
|
||||||
return Database.GetCollection<TDocument>(partitionKey +"-"+ Pluralize<TDocument>());
|
InitializeGuidRepresentation();
|
||||||
|
Client = client;
|
||||||
|
Database = client.GetDatabase(databaseName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a collection for a document type. Also handles document types with a partition key.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
|
||||||
|
/// <param name="partitionKey">The optional value of the partition key.</param>
|
||||||
|
public virtual IMongoCollection<TDocument> GetCollection<TDocument>(string partitionKey = null)
|
||||||
|
{
|
||||||
|
return Database.GetCollection<TDocument>(GetCollectionName<TDocument>(partitionKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Drops a collection, use very carefully.
|
/// Drops a collection, use very carefully.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
|
||||||
public void DropCollection<TDocument>()
|
public virtual void DropCollection<TDocument>(string partitionKey = null)
|
||||||
{
|
{
|
||||||
Database.DropCollection(Pluralize<TDocument>());
|
Database.DropCollection(GetCollectionName<TDocument>(partitionKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Drops a collection having a partitionkey, use very carefully.
|
/// Sets the Guid representation of the MongoDB Driver.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
/// <param name="guidRepresentation">The new value of the GuidRepresentation</param>
|
||||||
public void DropCollection<TDocument>(string partitionKey)
|
public virtual void SetGuidRepresentation(MongoDB.Bson.GuidRepresentation guidRepresentation)
|
||||||
{
|
{
|
||||||
Database.DropCollection(partitionKey + "-" + Pluralize<TDocument>());
|
MongoDefaults.GuidRepresentation = guidRepresentation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extracts the CollectionName attribute from the entity type, if any.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
|
||||||
|
/// <returns>The name of the collection in which the TDocument is stored.</returns>
|
||||||
|
protected virtual string GetAttributeCollectionName<TDocument>()
|
||||||
|
{
|
||||||
|
return (typeof(TDocument).GetTypeInfo()
|
||||||
|
.GetCustomAttributes(typeof(CollectionNameAttribute))
|
||||||
|
.FirstOrDefault() as CollectionNameAttribute)?.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize the Guid representation of the MongoDB Driver.
|
||||||
|
/// Override this method to change the default GuidRepresentation.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void InitializeGuidRepresentation()
|
||||||
|
{
|
||||||
|
// by default, avoid legacy UUID representation: use Binary 0x04 subtype.
|
||||||
|
MongoDefaults.GuidRepresentation = MongoDB.Bson.GuidRepresentation.Standard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Given the document type and the partition key, returns the name of the collection it belongs to.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
|
||||||
|
/// <param name="partitionKey">The value of the partition key.</param>
|
||||||
|
/// <returns>The name of the collection.</returns>
|
||||||
|
protected virtual string GetCollectionName<TDocument>(string partitionKey)
|
||||||
|
{
|
||||||
|
var collectionName = GetAttributeCollectionName<TDocument>() ?? Pluralize<TDocument>();
|
||||||
|
if (string.IsNullOrEmpty(partitionKey))
|
||||||
|
{
|
||||||
|
return collectionName;
|
||||||
|
}
|
||||||
|
return $"{partitionKey}-{collectionName}";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Very naively pluralizes a TDocument type name.
|
/// Very naively pluralizes a TDocument type name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TDocument"></typeparam>
|
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
|
||||||
/// <returns></returns>
|
/// <returns>The pluralized document name.</returns>
|
||||||
private string Pluralize<TDocument>()
|
protected virtual string Pluralize<TDocument>()
|
||||||
{
|
{
|
||||||
return (typeof(TDocument).Name.Pluralize()).Camelize();
|
return (typeof(TDocument).Name.Pluralize()).Camelize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,31 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net45;netstandard1.5;netstandard2.0</TargetFrameworks>
|
<TargetFrameworks>net452;netstandard2.0;netstandard1.5;</TargetFrameworks>
|
||||||
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<PackageId>MongoDbGenericRepository</PackageId>
|
<PackageId>MongoDbGenericRepository</PackageId>
|
||||||
<PackageVersion>1.2.0</PackageVersion>
|
<PackageVersion>1.4.6</PackageVersion>
|
||||||
<Authors>Alexandre Spieser</Authors>
|
<Authors>Alexandre Spieser</Authors>
|
||||||
|
<PackageTitle>MongoDb Generic Repository</PackageTitle>
|
||||||
<Description>A generic repository implementation using the MongoDB C# Sharp 2.0 driver.</Description>
|
<Description>A generic repository implementation using the MongoDB C# Sharp 2.0 driver.</Description>
|
||||||
|
<PackageLicenseUrl>http://www.opensource.org/licenses/mit-license.php</PackageLicenseUrl>
|
||||||
|
<PackageProjectUrl>http://www.opensource.org/licenses/mit-license.php</PackageProjectUrl>
|
||||||
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
||||||
<PackageReleaseNotes>.NET Core supported.</PackageReleaseNotes>
|
<PackageReleaseNotes>Release notes are at https://github.com/alexandre-spieser/mongodb-generic-repository/releases </PackageReleaseNotes>
|
||||||
<Copyright>Copyright 2017 (c) Alexandre Spieser. All rights reserved.</Copyright>
|
<Copyright>Copyright 2020 (c) Alexandre Spieser. All rights reserved.</Copyright>
|
||||||
<PackageTags>MongoDb Repository NoSql Generic</PackageTags>
|
<PackageTags>MongoDb Repository Generic NoSql</PackageTags>
|
||||||
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
|
<Version>1.4.6</Version>
|
||||||
|
<RepositoryUrl>https://github.com/alexandre-spieser/mongodb-generic-repository</RepositoryUrl>
|
||||||
|
<RepositoryType>Git</RepositoryType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net45|AnyCPU'">
|
<PropertyGroup>
|
||||||
<DocumentationFile>bin\Release\net45\MongoDbGenericRepository.xml</DocumentationFile>
|
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MongoDB.Driver" Version="2.4.4" />
|
<PackageReference Include="MongoDB.Driver" Version="2.12.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<package >
|
<package >
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MongoDbGenericRepository</id>
|
<id>MongoDbGenericRepository</id>
|
||||||
<version>1.2.1</version>
|
<version>1.4.5</version>
|
||||||
<title>MongoDb Generic Repository</title>
|
<title>MongoDb Generic Repository</title>
|
||||||
<authors>Alexandre Spieser</authors>
|
<authors>Alexandre Spieser</authors>
|
||||||
<owners>Alexandre Spieser</owners>
|
<owners>Alexandre Spieser</owners>
|
||||||
@@ -10,9 +10,20 @@
|
|||||||
<projectUrl>https://github.com/alexandre-spieser/mongodb-generic-repository</projectUrl>
|
<projectUrl>https://github.com/alexandre-spieser/mongodb-generic-repository</projectUrl>
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<description>A generic repository implementation using the MongoDB C# Sharp 2.0 driver.</description>
|
<description>A generic repository implementation using the MongoDB C# Sharp 2.0 driver.</description>
|
||||||
<releaseNotes>Exposed core MongoDb driver objects and removed the AddedAtUtc property constraint from the IDocument interface.</releaseNotes>
|
<releaseNotes>Release notes are at https://github.com/alexandre-spieser/mongodb-generic-repository/releases</releaseNotes>
|
||||||
<copyright>Copyright 2017 (c) Alexandre Spieser. All rights reserved.</copyright>
|
<copyright>Copyright 2020 (c) Alexandre Spieser. All rights reserved.</copyright>
|
||||||
<tags>MongoDb Repository Generic NoSql</tags>
|
<tags>MongoDb Repository Generic NoSql</tags>
|
||||||
|
<dependencies>
|
||||||
|
<group targetFramework=".NETFramework4.5.2">
|
||||||
|
<dependency id="MongoDB.Driver" version="2.9.3" exclude="Build,Analyzers" />
|
||||||
|
</group>
|
||||||
|
<group targetFramework=".NETStandard1.5">
|
||||||
|
<dependency id="MongoDB.Driver" version="2.9.3" exclude="Build,Analyzers" />
|
||||||
|
</group>
|
||||||
|
<group targetFramework=".NETStandard2.0">
|
||||||
|
<dependency id="MongoDB.Driver" version="2.9.3" exclude="Build,Analyzers"/>
|
||||||
|
</group>
|
||||||
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
<file src="lib\**" target="lib" />
|
<file src="lib\**" target="lib" />
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,681 @@
|
|||||||
|
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;
|
||||||
|
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 class ReadOnlyMongoRepository : ReadOnlyMongoRepository<Guid>, IReadOnlyMongoRepository
|
||||||
|
{
|
||||||
|
/// <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) : base(connectionString, databaseName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The contructor taking a <see cref="IMongoDbContext"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="mongoDbContext">A mongodb context implementing <see cref="IMongoDbContext"/></param>
|
||||||
|
protected ReadOnlyMongoRepository(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 ReadOnlyMongoRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#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>
|
||||||
|
{
|
||||||
|
return await MongoDbReader.GetByIdAsync<TDocument, TKey>(id, partitionKey, 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>
|
||||||
|
{
|
||||||
|
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>
|
||||||
|
/// <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 MongoDbReader.GetOneAsync<TDocument, TKey>(filter, partitionKey, 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 MongoDbReader.GetOne<TDocument, TKey>(filter, partitionKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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 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>
|
||||||
|
/// <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>
|
||||||
|
{
|
||||||
|
return await MongoDbReader.AnyAsync<TDocument, TKey>(filter, partitionKey, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
{
|
||||||
|
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>
|
||||||
|
/// <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 MongoDbReader.GetAllAsync<TDocument, TKey>(filter, partitionKey, 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 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>
|
||||||
|
/// <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 MongoDbReader.CountAsync<TDocument, TKey>(filter, partitionKey, 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 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>
|
||||||
|
/// <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 MongoDbReader.GetByMaxAsync<TDocument, TKey>(filter, maxValueSelector, partitionKey, 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 MongoDbReader.GetByMax<TDocument, TKey>(filter, maxValueSelector, partitionKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
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 MongoDbReader.GetByMinAsync<TDocument, TKey>(filter, minValueSelector, partitionKey, 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 for the minimum value you are looking for.</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 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="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>
|
||||||
|
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 MongoDbReader.GetMaxValueAsync<TDocument, TKey, TValue>(filter, maxValueSelector, partitionKey, 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 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="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 MongoDbReader.GetMinValueAsync<TDocument, TKey, TValue>(filter, minValueSelector, partitionKey, 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 MongoDbReader.GetMinValue<TDocument, TKey, TValue>(filter, minValueSelector, partitionKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#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.</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 MongoDbReader.SumByAsync<TDocument, TKey>(filter, selector, partitionKey, 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.</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 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>
|
||||||
|
/// <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>
|
||||||
|
public virtual async 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>
|
||||||
|
{
|
||||||
|
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>
|
||||||
|
/// <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>
|
||||||
|
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 MongoDbReader.SumBy<TDocument, TKey>(filter, selector, partitionKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Sum TKey
|
||||||
|
|
||||||
|
#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>
|
||||||
|
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 MongoDbReader.ProjectOneAsync<TDocument, TProjection, TKey>(filter, projection, partitionKey, 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 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="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 MongoDbReader.ProjectManyAsync<TDocument, TProjection, TKey>(filter, projection, partitionKey, 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 MongoDbReader.ProjectMany<TDocument, TProjection, TKey>(filter, projection, partitionKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Project TKey
|
||||||
|
|
||||||
|
#region Group By TKey
|
||||||
|
|
||||||
|
/// <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="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 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="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="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, 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()
|
||||||
|
{
|
||||||
|
return MongoDbReader.GroupBy<TDocument, TGroupKey, TProjection, TKey>(filter, groupingCriteria, groupProjection, partitionKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Group By TKey
|
||||||
|
|
||||||
|
|
||||||
|
#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>
|
||||||
|
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)
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Pagination
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
{
|
||||||
|
return MongoDbReader.HandlePartitioned<TDocument, TKey>(document);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
/// Gets a collections for a potentially partitioned document type.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TDocument">The document type.</typeparam>
|
||||||
|
/// <param name="document">The document.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public virtual IMongoCollection<TDocument> HandlePartitioned<TDocument>(TDocument document)
|
||||||
|
where TDocument : IDocument<Guid>
|
||||||
|
{
|
||||||
|
return MongoDbReader.HandlePartitioned<TDocument, Guid>(document);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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 MongoDbReader.GetCollection<TDocument, TKey>(partitionKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using MongoDB.Bson;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MongoDbGenericRepository.Utils
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The IdGenerator instance, used to generate Ids of different types.
|
||||||
|
/// </summary>
|
||||||
|
public static class IdGenerator
|
||||||
|
{
|
||||||
|
private static readonly Random Random = new Random();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a random value of a given type.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TKey">The type of the value to generate.</typeparam>
|
||||||
|
/// <returns>A value of type TKey.</returns>
|
||||||
|
public static TKey GetId<TKey>()
|
||||||
|
{
|
||||||
|
var idTypeName = typeof(TKey).Name;
|
||||||
|
switch (idTypeName)
|
||||||
|
{
|
||||||
|
case "Guid":
|
||||||
|
return (TKey)(object)Guid.NewGuid();
|
||||||
|
case "Int16":
|
||||||
|
return (TKey)(object)Random.Next(1, short.MaxValue);
|
||||||
|
case "Int32":
|
||||||
|
return (TKey)(object)Random.Next(1, int.MaxValue);
|
||||||
|
case "Int64":
|
||||||
|
return (TKey)(object)(Random.NextLong(1, long.MaxValue));
|
||||||
|
case "String":
|
||||||
|
return (TKey)(object)Guid.NewGuid().ToString();
|
||||||
|
case "ObjectId":
|
||||||
|
return (TKey)(object)ObjectId.GenerateNewId();
|
||||||
|
}
|
||||||
|
throw new ArgumentException($"{idTypeName} is not a supported Id type, the Id of the document cannot be set.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -64,7 +64,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace MongoDbGenericRepository
|
namespace MongoDbGenericRepository.Utils
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Container for registered Vocabularies. At present, only a single vocabulary is supported: Default.
|
/// Container for registered Vocabularies. At present, only a single vocabulary is supported: Default.
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MongoDbGenericRepository.Utils
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user