From d2f465b0631267924268adb0464b10a040b1f0b3 Mon Sep 17 00:00:00 2001 From: Alexandre SPIESER Date: Wed, 10 Apr 2019 23:48:44 +0100 Subject: [PATCH] reorg + inheritance setup, using interface segregation to split concern / exposure of methods. --- .../IKeyTypedReadOnlyMongoRepository.cs | 63 ++- .../Abstractions/IReadOnlyMongoRepository.cs | 266 +---------- .../BaseMongoDbRepository.cs | 5 +- ...goRepository.TKey.cs => BaseRepository.cs} | 426 +++++++++++++++++- .../KeyTypedBaseMongoDbRepository.cs | 5 +- .../KeyTypedReadOnlyMongoRepository.cs | 194 ++++---- .../MongoDbGenericRepository.csproj | 4 +- .../ReadOnlyMongoRepository.Maths.cs | 52 --- .../ReadOnlyMongoRepository.cs | 37 ++ 9 files changed, 600 insertions(+), 452 deletions(-) rename MongoDbGenericRepository/{ReadOnlyMongoRepository.TKey.cs => BaseRepository.cs} (50%) delete mode 100644 MongoDbGenericRepository/ReadOnlyMongoRepository.Maths.cs create mode 100644 MongoDbGenericRepository/ReadOnlyMongoRepository.cs diff --git a/MongoDbGenericRepository/Abstractions/IKeyTypedReadOnlyMongoRepository.cs b/MongoDbGenericRepository/Abstractions/IKeyTypedReadOnlyMongoRepository.cs index 857ee97..a2b42c1 100644 --- a/MongoDbGenericRepository/Abstractions/IKeyTypedReadOnlyMongoRepository.cs +++ b/MongoDbGenericRepository/Abstractions/IKeyTypedReadOnlyMongoRepository.cs @@ -7,17 +7,9 @@ using MongoDbGenericRepository.Models; namespace MongoDbGenericRepository { - public interface IKeyTypedReadOnlyMongoRepository where TKey : IEquatable + public interface IKeyTypedReadOnlyMongoRepository : IBaseReadOnlyRepository + where TKey : IEquatable { - /// - /// The connection string. - /// - string ConnectionString { get; set; } - /// - /// The database name. - /// - string DatabaseName { get; set; } - #region Read /// @@ -199,5 +191,56 @@ namespace MongoDbGenericRepository #endregion + #region Maths + + /// + /// 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; + + /// + /// 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. + int SumBy(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. + decimal SumBy(Expression> filter, + Expression> selector, + string partitionKey = null) + where TDocument : IDocument; + + #endregion Maths } } \ No newline at end of file diff --git a/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs b/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs index bfce1ec..a5e295e 100644 --- a/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs +++ b/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs @@ -1,273 +1,11 @@ -using MongoDB.Driver; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using System.Linq.Expressions; -using MongoDbGenericRepository.Models; +using System; namespace MongoDbGenericRepository { /// /// The IReadOnlyMongoRepository exposes the readonly functionality of the BaseMongoRepository. /// - public interface IReadOnlyMongoRepository : IKeyTypedReadOnlyMongoRepository + public interface IReadOnlyMongoRepository : IBaseReadOnlyRepository, IKeyTypedReadOnlyMongoRepository { - - #region Read TKey - - /// - /// Asynchronously returns one document given its id. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The Id of the document you want to get. - /// An optional partition key. - Task GetByIdAsync(TKey id, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Returns one document given its id. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The Id of the document you want to get. - /// An optional partition key. - TDocument GetById(TKey id, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Asynchronously returns one document given an expression filter. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - Task GetOneAsync(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Returns one document given an expression filter. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - TDocument GetOne(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Returns a collection cursor. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - IFindFluent GetCursor(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - - /// - /// Returns true if any of the document of the collection matches the filter condition. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - Task AnyAsync(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Returns true if any of the document of the collection matches the filter condition. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - bool Any(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Asynchronously returns a list of the documents matching the filter condition. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - Task> GetAllAsync(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Returns a list of the documents matching the filter condition. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - List GetAll(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Asynchronously counts how many documents match the filter condition. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partitionKey - Task CountAsync(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Counts how many documents match the filter condition. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partitionKey - long Count(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - #endregion - - #region Min / Max - - /// - /// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter. - /// - /// The document type. - /// The type of the primary key. - /// A LINQ expression filter. - /// A property selector to order by descending. - /// An optional partitionKey. - Task GetByMaxAsync(Expression> filter, Expression> orderByDescending, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter. - /// - /// The document type. - /// The type of the primary key. - /// A LINQ expression filter. - /// A property selector to order by descending. - /// An optional partitionKey. - TDocument GetByMax(Expression> filter, Expression> orderByDescending, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Gets the document with the minimum value of a specified property in a MongoDB collections that is satisfying the filter. - /// - /// The document type. - /// The type of the primary key. - /// A LINQ expression filter. - /// A property selector to order by ascending. - /// An optional partitionKey. - Task GetByMinAsync(Expression> filter, Expression> orderByAscending, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Gets the document with the minimum value of a specified property in a MongoDB collections that is satisfying the filter. - /// - /// The document type. - /// The type of the primary key. - /// A LINQ expression filter. - /// A property selector to order by ascending. - /// An optional partitionKey. - TDocument GetByMin(Expression> filter, Expression> orderByAscending, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Gets the maximum value of a property in a mongodb collections that is satisfying the filter. - /// - /// The document type. - /// The type of the primary key. - /// A LINQ expression filter. - /// A property selector to order by ascending. - /// An optional partitionKey. - Task GetMaxValueAsync(Expression> filter, Expression> maxValueSelector, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Gets the maximum value of a property in a mongodb collections that is satisfying the filter. - /// - /// The document type. - /// The type of the primary key. - /// A LINQ expression filter. - /// A property selector to order by ascending. - /// An optional partitionKey. - TValue GetMaxValue(Expression> filter, Expression> orderByDescending, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Gets the minimum value of a property in a mongodb collections that is satisfying the filter. - /// - /// The document type. - /// The type of the primary key. - /// The type of the value used to order the query. - /// A LINQ expression filter. - /// A property selector to order by ascending. - /// An optional partition key. - Task GetMinValueAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Gets the minimum value of a property in a mongodb collections that is satisfying the filter. - /// - /// The document type. - /// The type of the primary key. - /// The type of the value used to order the query. - /// A LINQ expression filter. - /// A property selector to order by ascending. - /// An optional partition key. - TValue GetMinValue(Expression> filter, Expression> minValueSelector, string partitionKey = null) - where TDocument : IDocument - 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 f8c9c75..db9dd3d 100644 --- a/MongoDbGenericRepository/BaseMongoDbRepository.cs +++ b/MongoDbGenericRepository/BaseMongoDbRepository.cs @@ -20,9 +20,8 @@ namespace MongoDbGenericRepository /// /// The connection string of the MongoDb server. /// The name of the database against which you want to perform operations. - protected BaseMongoRepository(string connectionString, string databaseName) : base(connectionString, databaseName) + protected BaseMongoRepository(string connectionString, string databaseName = null) : base(connectionString, databaseName) { - MongoDbContext = new MongoDbContext(connectionString, databaseName); } /// @@ -31,7 +30,6 @@ namespace MongoDbGenericRepository /// A mongodb context implementing protected BaseMongoRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext) { - MongoDbContext = mongoDbContext; } /// @@ -40,7 +38,6 @@ namespace MongoDbGenericRepository /// A mongodb context implementing protected BaseMongoRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase) { - MongoDbContext = new MongoDbContext(mongoDatabase); } #region Create diff --git a/MongoDbGenericRepository/ReadOnlyMongoRepository.TKey.cs b/MongoDbGenericRepository/BaseRepository.cs similarity index 50% rename from MongoDbGenericRepository/ReadOnlyMongoRepository.TKey.cs rename to MongoDbGenericRepository/BaseRepository.cs index b28890e..823c1f8 100644 --- a/MongoDbGenericRepository/ReadOnlyMongoRepository.TKey.cs +++ b/MongoDbGenericRepository/BaseRepository.cs @@ -9,37 +9,356 @@ using System.Threading.Tasks; 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 ReadOnlyMongoRepository : KeyTypedReadOnlyMongoRepository, IReadOnlyMongoRepository + public interface IBaseReadOnlyRepository { + /// + /// The connection string. + /// + string ConnectionString { get; } + + /// + /// The database name. + /// + string DatabaseName { get; } + + #region Read TKey + + /// + /// Asynchronously returns one document given its id. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The Id of the document you want to get. + /// An optional partition key. + Task GetByIdAsync(TKey id, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Returns one document given its id. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The Id of the document you want to get. + /// An optional partition key. + TDocument GetById(TKey id, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Asynchronously returns one document given an expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + Task GetOneAsync(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Returns one document given an expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + TDocument GetOne(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Returns a collection cursor. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + IFindFluent GetCursor(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + + /// + /// Returns true if any of the document of the collection matches the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + Task AnyAsync(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Returns true if any of the document of the collection matches the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + bool Any(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Asynchronously returns a list of the documents matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + Task> GetAllAsync(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Returns a list of the documents matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + List GetAll(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Asynchronously counts how many documents match the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partitionKey + Task CountAsync(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Counts how many documents match the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partitionKey + long Count(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + #endregion + + #region Min / Max + + /// + /// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter. + /// + /// The document type. + /// The type of the primary key. + /// A LINQ expression filter. + /// A property selector to order by descending. + /// An optional partitionKey. + Task GetByMaxAsync(Expression> filter, Expression> orderByDescending, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Gets the document with the maximum value of a specified property in a MongoDB collections that is satisfying the filter. + /// + /// The document type. + /// The type of the primary key. + /// A LINQ expression filter. + /// A property selector to order by descending. + /// An optional partitionKey. + TDocument GetByMax(Expression> filter, Expression> orderByDescending, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Gets the document with the minimum value of a specified property in a MongoDB collections that is satisfying the filter. + /// + /// The document type. + /// The type of the primary key. + /// A LINQ expression filter. + /// A property selector to order by ascending. + /// An optional partitionKey. + Task GetByMinAsync(Expression> filter, Expression> orderByAscending, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Gets the document with the minimum value of a specified property in a MongoDB collections that is satisfying the filter. + /// + /// The document type. + /// The type of the primary key. + /// A LINQ expression filter. + /// A property selector to order by ascending. + /// An optional partitionKey. + TDocument GetByMin(Expression> filter, Expression> orderByAscending, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Gets the maximum value of a property in a mongodb collections that is satisfying the filter. + /// + /// The document type. + /// The type of the primary key. + /// A LINQ expression filter. + /// A property selector to order by ascending. + /// An optional partitionKey. + Task GetMaxValueAsync(Expression> filter, Expression> maxValueSelector, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Gets the maximum value of a property in a mongodb collections that is satisfying the filter. + /// + /// The document type. + /// The type of the primary key. + /// A LINQ expression filter. + /// A property selector to order by ascending. + /// An optional partitionKey. + TValue GetMaxValue(Expression> filter, Expression> orderByDescending, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Gets the minimum value of a property in a mongodb collections that is satisfying the filter. + /// + /// The document type. + /// The type of the primary key. + /// The type of the value used to order the query. + /// A LINQ expression filter. + /// A property selector to order by ascending. + /// An optional partition key. + Task GetMinValueAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Gets the minimum value of a property in a mongodb collections that is satisfying the filter. + /// + /// The document type. + /// The type of the primary key. + /// The type of the value used to order the query. + /// A LINQ expression filter. + /// A property selector to order by ascending. + /// An optional partition key. + TValue GetMinValue(Expression> filter, Expression> minValueSelector, string partitionKey = null) + where TDocument : IDocument + 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 + where TKey : IEquatable; + + /// + /// 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. + int SumBy(Expression> filter, + Expression> selector, + string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// 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; + + /// + /// 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. + decimal SumBy(Expression> filter, + Expression> selector, + string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + #endregion Sum + } + + public class BaseReadOnlyRepository : IBaseReadOnlyRepository + { + /// + /// The connection string. + /// + public string ConnectionString { get; } + + /// + /// The database name. + /// + public string DatabaseName { get; } + + /// + /// The MongoDbContext + /// + protected IMongoDbContext MongoDbContext = null; + /// /// The constructor taking a connection string and a database name. /// /// The connection string of the MongoDb server. /// The name of the database against which you want to perform operations. - protected ReadOnlyMongoRepository(string connectionString, string databaseName) : base(connectionString, databaseName) + protected BaseReadOnlyRepository(string connectionString, string databaseName = null) { + if (databaseName == null) + { + var mongoUrl = new MongoUrl(connectionString); + databaseName = databaseName ?? mongoUrl.DatabaseName; + } + ConnectionString = connectionString; + DatabaseName = databaseName; + MongoDbContext = new MongoDbContext(connectionString, databaseName); } /// /// The contructor taking a . /// /// A mongodb context implementing - protected ReadOnlyMongoRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext) + protected BaseReadOnlyRepository(IMongoDbContext mongoDbContext) { + MongoDbContext = mongoDbContext; } /// /// The contructor taking a . /// /// A mongodb context implementing - protected ReadOnlyMongoRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase) + protected BaseReadOnlyRepository(IMongoDatabase mongoDatabase) { + MongoDbContext = new MongoDbContext(mongoDatabase); } + #region Read TKey /// @@ -378,8 +697,83 @@ namespace MongoDbGenericRepository #endregion + #region Sum TKey + + /// + /// 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 GetQuery(filter, partitionKey).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 int SumBy(Expression> filter, + Expression> selector, + string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return GetQuery(filter, partitionKey).Sum(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 GetQuery(filter, partitionKey).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 decimal SumBy(Expression> filter, + Expression> selector, + string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return GetQuery(filter, partitionKey).Sum(selector); + } + + #endregion Sums TKey + #region Utility Methods + protected IMongoQueryable GetQuery(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return GetCollection(partitionKey).AsQueryable().Where(filter); + } + /// /// Gets a collections for a potentially partitioned document type. /// @@ -430,6 +824,20 @@ namespace MongoDbGenericRepository return GetCollection(); } + /// + /// Converts a LINQ expression of TDocument, TValue to a LINQ expression of TDocument, object + /// + /// The document type. + /// The type of the value. + /// The expression to convert + protected static Expression> ConvertExpression(Expression> expression) + { + var param = expression.Parameters[0]; + Expression body = expression.Body; + var convert = Expression.Convert(body, typeof(object)); + return Expression.Lambda>(convert, param); + } + #endregion } -} \ No newline at end of file +} diff --git a/MongoDbGenericRepository/KeyTypedBaseMongoDbRepository.cs b/MongoDbGenericRepository/KeyTypedBaseMongoDbRepository.cs index 0adba7f..88d6f25 100644 --- a/MongoDbGenericRepository/KeyTypedBaseMongoDbRepository.cs +++ b/MongoDbGenericRepository/KeyTypedBaseMongoDbRepository.cs @@ -20,7 +20,7 @@ namespace MongoDbGenericRepository /// /// The connection string of the MongoDb server. /// The name of the database against which you want to perform operations. - protected KeyTypedBaseMongoDbRepository(string connectionString, string databaseName) : base(connectionString, databaseName) + protected KeyTypedBaseMongoDbRepository(string connectionString, string databaseName = null) : base(connectionString, databaseName) { } @@ -40,7 +40,6 @@ namespace MongoDbGenericRepository { } - #region Create /// @@ -129,7 +128,6 @@ namespace MongoDbGenericRepository #endregion Create - /// /// Sets the value of the document Id if it is not set already. /// @@ -149,6 +147,5 @@ namespace MongoDbGenericRepository document.Id = IdGenerator.GetId(); } } - } } diff --git a/MongoDbGenericRepository/KeyTypedReadOnlyMongoRepository.cs b/MongoDbGenericRepository/KeyTypedReadOnlyMongoRepository.cs index 7c41e7e..3f3d37f 100644 --- a/MongoDbGenericRepository/KeyTypedReadOnlyMongoRepository.cs +++ b/MongoDbGenericRepository/KeyTypedReadOnlyMongoRepository.cs @@ -9,55 +9,35 @@ using System.Threading.Tasks; 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 class KeyTypedReadOnlyMongoRepository : IKeyTypedReadOnlyMongoRepository where TKey : IEquatable + public abstract class KeyTypedReadOnlyMongoRepository : BaseReadOnlyRepository, IKeyTypedReadOnlyMongoRepository where TKey : IEquatable { - /// - /// The connection string. - /// - public string ConnectionString { get; set; } - - /// - /// The database name. - /// - public string DatabaseName { get; set; } - - /// - /// The MongoDbContext - /// - protected IMongoDbContext MongoDbContext = null; - /// /// The constructor taking a connection string and a database name. /// /// The connection string of the MongoDb server. /// The name of the database against which you want to perform operations. - protected KeyTypedReadOnlyMongoRepository(string connectionString, string databaseName) + protected KeyTypedReadOnlyMongoRepository(string connectionString, string databaseName = null) : base(connectionString, databaseName) { - MongoDbContext = new MongoDbContext(connectionString, databaseName); } /// /// The contructor taking a . /// /// A mongodb context implementing - protected KeyTypedReadOnlyMongoRepository(IMongoDbContext mongoDbContext) + protected KeyTypedReadOnlyMongoRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext) { - MongoDbContext = mongoDbContext; } /// /// The contructor taking a . /// /// A mongodb context implementing - protected KeyTypedReadOnlyMongoRepository(IMongoDatabase mongoDatabase) + protected KeyTypedReadOnlyMongoRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase) { - MongoDbContext = new MongoDbContext(mongoDatabase); } #region Read @@ -70,8 +50,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public async Task GetByIdAsync(TKey id, string partitionKey = null) where TDocument : IDocument { - var filter = Builders.Filter.Eq("Id", id); - return await HandlePartitioned(partitionKey).Find(filter).FirstOrDefaultAsync(); + return await base.GetByIdAsync(id, partitionKey); } /// @@ -82,8 +61,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public TDocument GetById(TKey id, string partitionKey = null) where TDocument : IDocument { - var filter = Builders.Filter.Eq("Id", id); - return HandlePartitioned(partitionKey).Find(filter).FirstOrDefault(); + return base.GetById(id, partitionKey); } /// @@ -94,7 +72,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public async Task GetOneAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return await HandlePartitioned(partitionKey).Find(filter).FirstOrDefaultAsync(); + return await base.GetOneAsync(filter, partitionKey); } /// @@ -105,7 +83,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public TDocument GetOne(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return HandlePartitioned(partitionKey).Find(filter).FirstOrDefault(); + return base.GetOne(filter, partitionKey); } /// @@ -116,7 +94,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public IFindFluent GetCursor(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return HandlePartitioned(partitionKey).Find(filter); + return base.GetCursor(filter, partitionKey); } /// @@ -127,8 +105,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public async Task AnyAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument { - var count = await HandlePartitioned(partitionKey).CountDocumentsAsync(filter); - return (count > 0); + return await base.AnyAsync(filter, partitionKey); } /// @@ -139,8 +116,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public bool Any(Expression> filter, string partitionKey = null) where TDocument : IDocument { - var count = HandlePartitioned(partitionKey).CountDocuments(filter); - return (count > 0); + return base.Any(filter, partitionKey); } /// @@ -151,7 +127,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public async Task> GetAllAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return await HandlePartitioned(partitionKey).Find(filter).ToListAsync(); + return await base.GetAllAsync(filter, partitionKey); } /// @@ -162,7 +138,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public List GetAll(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return HandlePartitioned(partitionKey).Find(filter).ToList(); + return base.GetAll(filter, partitionKey); } /// @@ -173,7 +149,7 @@ namespace MongoDbGenericRepository /// An optional partitionKey public async Task CountAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return await HandlePartitioned(partitionKey).CountDocumentsAsync(filter); + return await base.CountAsync(filter, partitionKey); } /// @@ -184,7 +160,7 @@ namespace MongoDbGenericRepository /// An optional partitionKey public long Count(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return HandlePartitioned(partitionKey).Find(filter).CountDocuments(); + return base.Count(filter, partitionKey); } /// @@ -197,10 +173,7 @@ namespace MongoDbGenericRepository public async Task GetByMaxAsync(Expression> filter, Expression> maxValueSelector, string partitionKey = null) where TDocument : IDocument { - return await GetCollection(partitionKey).Find(Builders.Filter.Where(filter)) - .SortByDescending(maxValueSelector) - .Limit(1) - .FirstOrDefaultAsync(); + return await base.GetByMaxAsync(filter, maxValueSelector, partitionKey); } /// @@ -214,10 +187,7 @@ namespace MongoDbGenericRepository public TDocument GetByMax(Expression> filter, Expression> maxValueSelector, string partitionKey = null) where TDocument : IDocument { - return GetCollection(partitionKey).Find(Builders.Filter.Where(filter)) - .SortByDescending(maxValueSelector) - .Limit(1) - .FirstOrDefault(); + return base.GetByMax(filter, maxValueSelector, partitionKey); } /// @@ -230,10 +200,7 @@ namespace MongoDbGenericRepository public async Task GetByMinAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null) where TDocument : IDocument { - return await GetCollection(partitionKey).Find(Builders.Filter.Where(filter)) - .SortBy(minValueSelector) - .Limit(1) - .FirstOrDefaultAsync(); + return await base.GetByMinAsync(filter, minValueSelector, partitionKey); } /// @@ -246,10 +213,7 @@ namespace MongoDbGenericRepository public TDocument GetByMin(Expression> filter, Expression> minValueSelector, string partitionKey = null) where TDocument : IDocument { - return GetCollection(partitionKey).Find(Builders.Filter.Where(filter)) - .SortBy(minValueSelector) - .Limit(1) - .FirstOrDefault(); + return base.GetByMin(filter, minValueSelector, partitionKey); } /// @@ -263,7 +227,7 @@ namespace MongoDbGenericRepository public async Task GetMaxValueAsync(Expression> filter, Expression> maxValueSelector, string partitionKey = null) where TDocument : IDocument { - return await GetMaxMongoQuery(filter, maxValueSelector, partitionKey).Project(maxValueSelector).FirstOrDefaultAsync(); + return await base.GetMaxValueAsync(filter, maxValueSelector, partitionKey); } /// @@ -277,7 +241,7 @@ namespace MongoDbGenericRepository public TValue GetMaxValue(Expression> filter, Expression> maxValueSelector, string partitionKey = null) where TDocument : IDocument { - return GetMaxMongoQuery(filter, maxValueSelector, partitionKey).Project(maxValueSelector).FirstOrDefault(); + return base.GetMaxValue(filter, maxValueSelector, partitionKey); } /// @@ -291,7 +255,7 @@ namespace MongoDbGenericRepository public virtual async Task GetMinValueAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null) where TDocument : IDocument { - return await GetMinMongoQuery(filter, minValueSelector, partitionKey).Project(minValueSelector).FirstOrDefaultAsync(); + return await base.GetMinValueAsync(filter, minValueSelector, partitionKey); } /// @@ -305,11 +269,75 @@ namespace MongoDbGenericRepository public virtual TValue GetMinValue(Expression> filter, Expression> minValueSelector, string partitionKey = null) where TDocument : IDocument { - return GetMinMongoQuery(filter, minValueSelector, partitionKey).Project(minValueSelector).FirstOrDefault(); + return base.GetMinValue(filter, minValueSelector, partitionKey); } #endregion + #region Maths + + /// + /// 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 + { + return await base.SumByAsync(filter, selector, partitionKey); + } + + /// + /// 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 + { + return await base.SumByAsync(filter, selector, partitionKey); + } + + /// + /// 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 int SumBy(Expression> filter, + Expression> selector, + string partitionKey = null) + where TDocument : IDocument + { + return base.SumBy(filter, selector, partitionKey); + } + + /// + /// 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 decimal SumBy(Expression> filter, + Expression> selector, + string partitionKey = null) + where TDocument : IDocument + { + return base.SumBy(filter, selector, partitionKey); + } + + #endregion Maths + #region Utility Methods /// @@ -357,54 +385,6 @@ namespace MongoDbGenericRepository return GetCollection(); } - /// - /// Converts a LINQ expression of TDocument, TValue to a LINQ expression of TDocument, object - /// - /// The document type. - /// The type of the value. - /// The expression to convert - protected static Expression> ConvertExpression(Expression> expression) - { - var param = expression.Parameters[0]; - Expression body = expression.Body; - var convert = Expression.Convert(body, typeof(object)); - return Expression.Lambda>(convert, param); - } - - /// - /// Gets the minimum value of a property in a mongodb collections that is satisfying the filter. - /// - /// The document type. - /// The type of the primary key. - /// The type of the value used to order the query. - /// A LINQ expression filter. - /// A property selector to order by ascending. - /// An optional partition key. - private IFindFluent GetMinMongoQuery(Expression> filter, Expression> minValueSelector, string partitionKey = null) - where TDocument : IDocument - { - return GetCollection(partitionKey).Find(Builders.Filter.Where(filter)) - .SortBy(ConvertExpression(minValueSelector)) - .Limit(1); - } - - /// - /// Gets the minimum value of a property in a mongodb collections that is satisfying the filter. - /// - /// The document type. - /// The type of the primary key. - /// The type of the value used to order the query. - /// A LINQ expression filter. - /// A property selector to order by descending. - /// An optional partition key. - private IFindFluent GetMaxMongoQuery(Expression> filter, Expression> maxValueSelector, string partitionKey = null) - where TDocument : IDocument - { - return GetCollection(partitionKey).Find(Builders.Filter.Where(filter)) - .SortByDescending(ConvertExpression(maxValueSelector)) - .Limit(1); - } - #endregion } } \ No newline at end of file diff --git a/MongoDbGenericRepository/MongoDbGenericRepository.csproj b/MongoDbGenericRepository/MongoDbGenericRepository.csproj index bed1e2f..55a2c7d 100644 --- a/MongoDbGenericRepository/MongoDbGenericRepository.csproj +++ b/MongoDbGenericRepository/MongoDbGenericRepository.csproj @@ -1,7 +1,7 @@ - + - net45;netstandard1.5;netstandard2.0 + net45;netstandard2.0;netstandard1.5; MongoDbGenericRepository 1.2.0 Alexandre Spieser diff --git a/MongoDbGenericRepository/ReadOnlyMongoRepository.Maths.cs b/MongoDbGenericRepository/ReadOnlyMongoRepository.Maths.cs deleted file mode 100644 index b75fe11..0000000 --- a/MongoDbGenericRepository/ReadOnlyMongoRepository.Maths.cs +++ /dev/null @@ -1,52 +0,0 @@ -using MongoDB.Driver; -using MongoDB.Driver.Linq; -using MongoDbGenericRepository.Models; -using System; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; - -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 ReadOnlyMongoRepository - { - /// - /// 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 - { - return await SumByAsync(filter, selector, partitionKey); - } - - /// - /// 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); - } - - } -} \ No newline at end of file diff --git a/MongoDbGenericRepository/ReadOnlyMongoRepository.cs b/MongoDbGenericRepository/ReadOnlyMongoRepository.cs new file mode 100644 index 0000000..fe995a9 --- /dev/null +++ b/MongoDbGenericRepository/ReadOnlyMongoRepository.cs @@ -0,0 +1,37 @@ +using MongoDB.Driver; +using System; + +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 class ReadOnlyMongoRepository : KeyTypedReadOnlyMongoRepository, IReadOnlyMongoRepository + { + /// + /// The constructor taking a connection string and a database name. + /// + /// The connection string of the MongoDb server. + /// The name of the database against which you want to perform operations. + protected ReadOnlyMongoRepository(string connectionString, string databaseName = null) : base(connectionString, databaseName) + { + } + + /// + /// The contructor taking a . + /// + /// A mongodb context implementing + protected ReadOnlyMongoRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext) + { + } + + /// + /// The contructor taking a . + /// + /// A mongodb context implementing + protected ReadOnlyMongoRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase) + { + } + } +} \ No newline at end of file