diff --git a/CoreIntegrationTests/CoreIntegrationTests.csproj b/CoreIntegrationTests/CoreIntegrationTests.csproj
index a3ba78f..720179b 100644
--- a/CoreIntegrationTests/CoreIntegrationTests.csproj
+++ b/CoreIntegrationTests/CoreIntegrationTests.csproj
@@ -9,13 +9,16 @@
-
+
+
+
+
..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Configuration.dll
diff --git a/CoreIntegrationTests/Infrastructure/MongoDbDocumentTestBase.cs b/CoreIntegrationTests/Infrastructure/MongoDbDocumentTestBase.cs
index 8c6fc2e..c70056c 100644
--- a/CoreIntegrationTests/Infrastructure/MongoDbDocumentTestBase.cs
+++ b/CoreIntegrationTests/Infrastructure/MongoDbDocumentTestBase.cs
@@ -1075,6 +1075,33 @@ namespace CoreIntegrationTests.Infrastructure
#endregion Index Management
+ #region Math
+
+ [Fact]
+ public async Task SumByAsync()
+ {
+ // Arrange
+ var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}";
+ var documents = CreateTestDocuments(5);
+ var i = 1;
+ documents.ForEach(e =>
+ {
+ e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++);
+ e.Nested.SomeAmount = 5m;
+ e.SomeContent = criteria;
+ });
+ SUT.AddMany(documents);
+ var expectedSum = documents.Sum(e => e.Nested.SomeAmount);
+
+ // Act
+ var result = await SUT.SumByAsync(e => e.SomeContent == criteria, e => e.Nested.SomeAmount, PartitionKey);
+
+ // Assert
+ Assert.Equal(expectedSum, result);
+ }
+
+ #endregion Math
+
#region Test Utils
[MethodImpl(MethodImplOptions.NoInlining)]
diff --git a/CoreIntegrationTests/Infrastructure/MongoDbTKeyDocumentTestBase.cs b/CoreIntegrationTests/Infrastructure/MongoDbTKeyDocumentTestBase.cs
index 98376f5..9d99665 100644
--- a/CoreIntegrationTests/Infrastructure/MongoDbTKeyDocumentTestBase.cs
+++ b/CoreIntegrationTests/Infrastructure/MongoDbTKeyDocumentTestBase.cs
@@ -1068,6 +1068,33 @@ namespace CoreIntegrationTests.Infrastructure
#endregion Index Management
+ #region Math
+
+ [Fact]
+ public async Task SumByAsync()
+ {
+ // Arrange
+ var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}";
+ var documents = CreateTestDocuments(5);
+ var i = 1;
+ documents.ForEach(e =>
+ {
+ e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++);
+ e.Nested.SomeAmount = 5m;
+ e.SomeContent = criteria;
+ });
+ SUT.AddMany(documents);
+ var expectedSum = documents.Sum(e => e.Nested.SomeAmount);
+
+ // Act
+ var result = await SUT.SumByAsync(e => e.SomeContent == criteria, e => e.Nested.SomeAmount, PartitionKey);
+
+ // Assert
+ Assert.Equal(expectedSum, result);
+ }
+
+ #endregion Math
+
#region Test Utils
[MethodImpl(MethodImplOptions.NoInlining)]
private string GetCurrentMethod()
diff --git a/CoreIntegrationTests/Infrastructure/TestClasses.cs b/CoreIntegrationTests/Infrastructure/TestClasses.cs
index 20b7fc2..c9ad2b9 100644
--- a/CoreIntegrationTests/Infrastructure/TestClasses.cs
+++ b/CoreIntegrationTests/Infrastructure/TestClasses.cs
@@ -1,4 +1,5 @@
-using MongoDB.Bson.Serialization.Attributes;
+using MongoDB.Bson;
+using MongoDB.Bson.Serialization.Attributes;
using MongoDbGenericRepository.Models;
using MongoDbGenericRepository.Utils;
using System;
@@ -21,6 +22,8 @@ namespace CoreIntegrationTests.Infrastructure
public class Nested
{
public DateTime SomeDate { get; set; }
+ [BsonRepresentation(BsonType.Decimal128)]
+ public decimal SomeAmount { get; set; }
}
public class Child
diff --git a/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs b/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs
index 2632d66..a79d3e9 100644
--- a/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs
+++ b/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs
@@ -425,6 +425,34 @@ namespace MongoDbGenericRepository
where TKey : IEquatable;
#endregion
+
+ #region Sum
+
+ ///
+ /// Sums the values of a selected field for a given filtered collection of documents.
+ ///
+ /// The type representing a Document.
+ /// A LINQ expression filter.
+ /// The field you want to sum.
+ /// The partition key of your document, if any.
+ Task SumByAsync(Expression> filter,
+ Expression> selector,
+ string partitionKey = null)
+ where TDocument : IDocument;
+
+ ///
+ /// Sums the values of a selected field for a given filtered collection of documents.
+ ///
+ /// The type representing a Document.
+ /// A LINQ expression filter.
+ /// The field you want to sum.
+ /// The partition key of your document, if any.
+ Task SumByAsync(Expression> filter,
+ Expression> selector,
+ string partitionKey = null)
+ where TDocument : IDocument
+ where TKey : IEquatable;
+ #endregion Sum
}
}
diff --git a/MongoDbGenericRepository/BaseMongoDbRepository.cs b/MongoDbGenericRepository/BaseMongoDbRepository.cs
index 2a3f07e..f8c9c75 100644
--- a/MongoDbGenericRepository/BaseMongoDbRepository.cs
+++ b/MongoDbGenericRepository/BaseMongoDbRepository.cs
@@ -1022,10 +1022,46 @@ namespace MongoDbGenericRepository
///
/// The type representing a Document.
/// A LINQ expression filter.
+ /// The property selector.
+ /// Order of the sorting.
/// The number of documents you want to skip. Default value is 0.
/// The number of documents you want to take. Default value is 50.
/// An optional partition key.
- public virtual async Task> GetPaginatedAsync(Expression> filter, int skipNumber = 0, int takeNumber = 50, string partitionKey = null)
+ public virtual async Task> GetSortedPaginatedAsync(
+ Expression> filter,
+ Expression> sortSelector,
+ bool ascending = true,
+ int skipNumber = 0,
+ int takeNumber = 50,
+ string partitionKey = null)
+ where TDocument : IDocument
+ {
+ var sorting = ascending
+ ? Builders.Sort.Ascending(sortSelector)
+ : Builders.Sort.Descending(sortSelector);
+
+ return await HandlePartitioned(partitionKey)
+ .Find(filter)
+ .Sort(sorting)
+ .Skip(skipNumber)
+ .Limit(takeNumber)
+ .ToListAsync();
+ }
+
+
+ ///
+ /// Asynchronously returns a paginated list of the documents matching the filter condition.
+ ///
+ /// The type representing a Document.
+ /// A LINQ expression filter.
+ /// The number of documents you want to skip. Default value is 0.
+ /// The number of documents you want to take. Default value is 50.
+ /// An optional partition key.
+ public virtual async Task> GetPaginatedAsync(
+ Expression> filter,
+ int skipNumber = 0,
+ int takeNumber = 50,
+ string partitionKey = null)
where TDocument : IDocument
{
return await HandlePartitioned(partitionKey).Find(filter).Skip(skipNumber).Limit(takeNumber).ToListAsync();
diff --git a/MongoDbGenericRepository/BaseMongoDbRepository.Maths.cs b/MongoDbGenericRepository/ReadOnlyMongoRepository.Maths.cs
similarity index 50%
rename from MongoDbGenericRepository/BaseMongoDbRepository.Maths.cs
rename to MongoDbGenericRepository/ReadOnlyMongoRepository.Maths.cs
index bbc6552..b75fe11 100644
--- a/MongoDbGenericRepository/BaseMongoDbRepository.Maths.cs
+++ b/MongoDbGenericRepository/ReadOnlyMongoRepository.Maths.cs
@@ -12,7 +12,7 @@ namespace MongoDbGenericRepository
/// 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.
///
- public abstract partial class BaseMongoRepository : ReadOnlyMongoRepository, IBaseMongoRepository
+ public abstract partial class ReadOnlyMongoRepository
{
///
/// Sums the values of a selected field for a given filtered collection of documents.
@@ -26,11 +26,26 @@ namespace MongoDbGenericRepository
string partitionKey = null)
where TDocument : IDocument
{
- var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey);
+ return await SumByAsync(filter, selector, partitionKey);
+ }
- return await collection.AsQueryable()
- .Where(filter)
- .SumAsync(selector);
+ ///
+ /// Sums the values of a selected field for a given filtered collection of documents.
+ ///
+ /// The type representing a Document.
+ /// A LINQ expression filter.
+ /// The field you want to sum.
+ /// The partition key of your document, if any.
+ public virtual async Task SumByAsync(Expression> filter,
+ Expression> selector,
+ string partitionKey = null)
+ where TDocument : IDocument
+ where TKey : IEquatable
+ {
+ return await GetCollection(partitionKey)
+ .AsQueryable()
+ .Where(filter)
+ .SumAsync(selector);
}
}
diff --git a/MongoDbGenericRepository/ReadOnlyMongoRepository.cs b/MongoDbGenericRepository/ReadOnlyMongoRepository.cs
index 0a8adb9..7638cdb 100644
--- a/MongoDbGenericRepository/ReadOnlyMongoRepository.cs
+++ b/MongoDbGenericRepository/ReadOnlyMongoRepository.cs
@@ -11,7 +11,7 @@ namespace MongoDbGenericRepository
///
/// The ReadOnlyMongoRepository implements the readonly functionality of the IReadOnlyMongoRepository.
///
- public class ReadOnlyMongoRepository : IReadOnlyMongoRepository
+ public abstract partial class ReadOnlyMongoRepository : IReadOnlyMongoRepository
{
///
/// The connection string.
@@ -578,7 +578,7 @@ namespace MongoDbGenericRepository
/// A LINQ expression filter.
/// A property selector to order by ascending.
/// An optional partition key.
- public async Task GetMinValueAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null)
+ public virtual async Task GetMinValueAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null)
where TDocument : IDocument
{
return await GetMinValueAsync(filter, minValueSelector, partitionKey);
@@ -593,7 +593,7 @@ namespace MongoDbGenericRepository
/// A LINQ expression filter.
/// A property selector to order by ascending.
/// An optional partition key.
- public async Task GetMinValueAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null)
+ public virtual async Task GetMinValueAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
@@ -608,7 +608,7 @@ namespace MongoDbGenericRepository
/// A LINQ expression filter.
/// A property selector to order by ascending.
/// An optional partition key.
- public TValue GetMinValue(Expression> filter, Expression> minValueSelector, string partitionKey = null)
+ public virtual TValue GetMinValue(Expression> filter, Expression> minValueSelector, string partitionKey = null)
where TDocument : IDocument
{
return GetMinValue(filter, minValueSelector, partitionKey);
@@ -623,7 +623,7 @@ namespace MongoDbGenericRepository
/// A LINQ expression filter.
/// A property selector to order by ascending.
/// An optional partition key.
- public TValue GetMinValue(Expression> filter, Expression> minValueSelector, string partitionKey = null)
+ public virtual TValue GetMinValue(Expression> filter, Expression> minValueSelector, string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
@@ -640,7 +640,7 @@ namespace MongoDbGenericRepository
/// The document type.
/// An optional partition key.
/// An
- protected IMongoCollection GetCollection(string partitionKey = null) where TDocument : IDocument
+ protected virtual IMongoCollection GetCollection(string partitionKey = null) where TDocument : IDocument
{
return MongoDbContext.GetCollection(partitionKey);
}
@@ -651,7 +651,7 @@ namespace MongoDbGenericRepository
/// The document type.
/// The document.
///
- protected IMongoCollection HandlePartitioned(TDocument document) where TDocument : IDocument
+ protected virtual IMongoCollection HandlePartitioned(TDocument document) where TDocument : IDocument
{
if (document is IPartitionedDocument)
{
@@ -667,7 +667,7 @@ namespace MongoDbGenericRepository
/// The type of the primary key.
/// The document.
///
- protected IMongoCollection HandlePartitioned(TDocument document)
+ protected virtual IMongoCollection HandlePartitioned(TDocument document)
where TDocument : IDocument
where TKey : IEquatable
{
@@ -684,7 +684,7 @@ namespace MongoDbGenericRepository
/// The document type.
/// The collection partition key.
///
- protected IMongoCollection HandlePartitioned(string partitionKey) where TDocument : IDocument
+ protected virtual IMongoCollection HandlePartitioned(string partitionKey) where TDocument : IDocument
{
if (!string.IsNullOrEmpty(partitionKey))
{
@@ -700,7 +700,7 @@ namespace MongoDbGenericRepository
/// The type of the primary key.
/// The collection partition key.
///
- protected IMongoCollection GetCollection(string partitionKey = null)
+ protected virtual IMongoCollection GetCollection(string partitionKey = null)
where TDocument : IDocument
where TKey : IEquatable
{
@@ -714,7 +714,7 @@ namespace MongoDbGenericRepository
/// The type of the primary key.
/// The collection partition key.
///
- protected IMongoCollection HandlePartitioned(string partitionKey)
+ protected virtual IMongoCollection HandlePartitioned(string partitionKey)
where TDocument : IDocument
where TKey : IEquatable
{