diff --git a/MongoDbGenericRepository/Abstractions/IBaseMongoRepository.cs b/MongoDbGenericRepository/Abstractions/IBaseMongoRepository.cs index 64d9e99..9f7b39f 100644 --- a/MongoDbGenericRepository/Abstractions/IBaseMongoRepository.cs +++ b/MongoDbGenericRepository/Abstractions/IBaseMongoRepository.cs @@ -8,604 +8,12 @@ using System.Linq; namespace MongoDbGenericRepository { - /// /// The IBaseMongoRepository exposes the CRUD functionality of the BaseMongoRepository. /// - public interface IBaseMongoRepository : IReadOnlyMongoRepository, IMongoDbCollectionIndexRepository + public interface IBaseMongoRepository : IReadOnlyMongoRepository, IBaseMongoRepository_Create, IBaseMongoRepository_Update, IBaseMongoRepository_Delete, IBaseMongoRepository_Index { - #region Create - /// - /// Asynchronously adds a document to the collection. - /// - /// The type representing a Document. - /// The document you want to add. - Task AddOneAsync(TDocument document) where TDocument : IDocument; - - /// - /// Adds a document to the collection. - /// Populates the Id and AddedAtUtc fields if necessary. - /// - /// The type representing a Document. - /// The document you want to add. - void AddOne(TDocument document) where TDocument : IDocument; - - /// - /// Asynchronously adds a list of documents to the collection. - /// Populates the Id and AddedAtUtc fields if necessary. - /// - /// The type representing a Document. - /// The document you want to add. - Task AddManyAsync(IEnumerable documents) where TDocument : IDocument; - - /// - /// Adds a list of documents to the collection. - /// Populates the Id and AddedAtUtc fields if necessary. - /// - /// The type representing a Document. - /// The document you want to add. - void AddMany(IEnumerable documents) where TDocument : IDocument; - - #endregion - - #region Create TKey - - /// - /// Asynchronously adds a document to the collection. - /// Populates the Id and AddedAtUtc fields if necessary. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document you want to add. - Task AddOneAsync(TDocument document) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Adds a document to the collection. - /// Populates the Id and AddedAtUtc fields if necessary. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document you want to add. - void AddOne(TDocument document) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Asynchronously adds a list of documents to the collection. - /// Populates the Id and AddedAtUtc fields if necessary. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The documents you want to add. - Task AddManyAsync(IEnumerable documents) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Adds a list of documents to the collection. - /// Populates the Id and AddedAtUtc fields if necessary. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The documents you want to add. - void AddMany(IEnumerable documents) - where TDocument : IDocument - where TKey : IEquatable; - - #endregion - - #region Update - - /// - /// Asynchronously Updates a document. - /// - /// The type representing a Document. - /// The document with the modifications you want to persist. - Task UpdateOneAsync(TDocument modifiedDocument) where TDocument : IDocument; - - /// - /// Updates a document. - /// - /// The type representing a Document. - /// The document with the modifications you want to persist. - bool UpdateOne(TDocument modifiedDocument) where TDocument : IDocument; - - /// - /// Updates the property field with the given value update a property field in entities. - /// - /// The type representing a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The value of the partition key. - bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument; - - /// - /// Updates the property field with the given value update a property field in entities. - /// - /// The type representing a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The value of the partition key. - Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument; - - /// - /// Updates the property field with the given value update a property field in entities. - /// - /// The type representing a Document. - /// The type of the field. - /// The document you want to modify. - /// The field selector. - /// The new value of the property field. - bool UpdateOne(TDocument documentToModify, Expression> field, TField value) - where TDocument : IDocument; - - /// - /// Updates the property field with the given value update a property field in entities. - /// - /// The type representing a Document. - /// The type of the field. - /// The document you want to modify. - /// The field selector. - /// The new value of the property field. - Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) - where TDocument : IDocument; - - /// - /// For the entity selected by the filter, updates the property field with the given value. - /// - /// The type representing a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The partition key for the document. - bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument; - - /// - /// Takes a document you want to modify and applies the update you have defined in MongoDb. - /// - /// The type representing a Document. - /// The document you want to modify. - /// The update definition for the document. - Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) - where TDocument : IDocument; - - /// - /// For the entity selected by the filter, updates the property field with the given value. - /// - /// The type representing a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The partition key for the document. - Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument; - - /// - /// Takes a document you want to modify and applies the update you have defined in MongoDb. - /// - /// The type representing a Document. - /// The document you want to modify. - /// The update definition for the document. - bool UpdateOne(TDocument documentToModify, UpdateDefinition update) - where TDocument : IDocument; - - #endregion - - #region Update TKey - - /// - /// Asynchronously Updates a document. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document with the modifications you want to persist. - Task UpdateOneAsync(TDocument modifiedDocument) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Updates a document. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document with the modifications you want to persist. - bool UpdateOne(TDocument modifiedDocument) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Takes a document you want to modify and applies the update you have defined in MongoDb. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document you want to modify. - /// The update definition for the document. - Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Takes a document you want to modify and applies the update you have defined in MongoDb. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document you want to modify. - /// The update definition for the document. - bool UpdateOne(TDocument documentToModify, UpdateDefinition update) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// For the entity selected by the filter, updates the property field with the given value.. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The partition key for the document. - bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Updates the property field with the given value update a property field in entities. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type of the field. - /// The document you want to modify. - /// The field selector. - /// The new value of the property field. - Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// For the entity selected by the filter, updates the property field with the given value. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The partition key for the document. - Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Updates the property field with the given value update a property field in entities. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type of the field. - /// The document you want to modify. - /// The field selector. - /// The new value of the property field. - bool UpdateOne(TDocument documentToModify, Expression> field, TField value) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Updates the property field with the given value update a property field in entities. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The value of the partition key. - Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Updates the property field with the given value update a property field in entities. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The value of the partition key. - bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - #endregion - - #region Delete - - /// - /// Asynchronously deletes a document. - /// - /// The type representing a Document. - /// The document you want to delete. - /// The number of documents deleted. - Task DeleteOneAsync(TDocument document) where TDocument : IDocument; - - /// - /// Asynchronously deletes a document matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - Task DeleteOneAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument; - - /// - /// Deletes a document. - /// - /// The type representing a Document. - /// The document you want to delete. - /// The number of documents deleted. - long DeleteOne(TDocument document) where TDocument : IDocument; - - /// - /// Deletes a document matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - long DeleteOne(Expression> filter, string partitionKey = null) where TDocument : IDocument; - - /// - /// Asynchronously deletes the documents matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - Task DeleteManyAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument; - - /// - /// Asynchronously deletes a list of documents. - /// - /// The type representing a Document. - /// The list of documents to delete. - /// The number of documents deleted. - Task DeleteManyAsync(IEnumerable documents) where TDocument : IDocument; - - /// - /// Deletes a list of documents. - /// - /// The type representing a Document. - /// The list of documents to delete. - /// The number of documents deleted. - long DeleteMany(IEnumerable documents) where TDocument : IDocument; - - /// - /// Deletes the documents matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - long DeleteMany(Expression> filter, string partitionKey = null) where TDocument : IDocument; - - #endregion - - #region Delete TKey - - /// - /// Deletes a document. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document you want to delete. - /// The number of documents deleted. - long DeleteOne(TDocument document) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Asynchronously deletes a document matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document you want to delete. - /// The number of documents deleted. - Task DeleteOneAsync(TDocument document) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Deletes a document matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - long DeleteOne(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Asynchronously deletes a document matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - Task DeleteOneAsync(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Asynchronously deletes the documents matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - Task DeleteManyAsync(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Asynchronously deletes a list of documents. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The list of documents to delete. - /// The number of documents deleted. - Task DeleteManyAsync(IEnumerable documents) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Deletes a list of documents. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The list of documents to delete. - /// The number of documents deleted. - long DeleteMany(IEnumerable documents) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Deletes the documents matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - long DeleteMany(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - #endregion - - #region Project - - /// - /// Asynchronously returns a projected document matching the filter condition. - /// - /// The type representing a Document. - /// The type representing the model you want to project to. - /// - /// The projection expression. - /// An optional partition key. - Task ProjectOneAsync(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TProjection : class; - - /// - /// Asynchronously returns a projected document matching the filter condition. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type representing the model you want to project to. - /// - /// The projection expression. - /// An optional partition key. - Task ProjectOneAsync(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - where TProjection : class; - - /// - /// Returns a projected document matching the filter condition. - /// - /// The type representing a Document. - /// The type representing the model you want to project to. - /// - /// The projection expression. - /// An optional partition key. - TProjection ProjectOne(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TProjection : class; - - /// - /// Returns a projected document matching the filter condition. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type representing the model you want to project to. - /// - /// The projection expression. - /// An optional partition key. - TProjection ProjectOne(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - where TProjection : class; - - /// - /// Asynchronously returns a list of projected documents matching the filter condition. - /// - /// The type representing a Document. - /// The type representing the model you want to project to. - /// - /// The projection expression. - /// An optional partition key. - Task> ProjectManyAsync(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TProjection : class; - - /// - /// Asynchronously returns a list of projected documents matching the filter condition. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type representing the model you want to project to. - /// - /// The projection expression. - /// An optional partition key. - Task> ProjectManyAsync(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - where TProjection : class; - - /// - /// Asynchronously returns a list of projected documents matching the filter condition. - /// - /// The type representing a Document. - /// The type representing the model you want to project to. - /// - /// The projection expression. - /// An optional partition key. - List ProjectMany(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TProjection : class; - - /// - /// Asynchronously returns a list of projected documents matching the filter condition. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type representing the model you want to project to. - /// - /// The projection expression. - /// An optional partition key. - List ProjectMany(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - where TProjection : class; - - #endregion /// /// Asynchronously returns a paginated list of the documents matching the filter condition. @@ -654,45 +62,6 @@ namespace MongoDbGenericRepository Task GetAndUpdateOne(FilterDefinition filter, UpdateDefinition update, FindOneAndUpdateOptions options) where TDocument : IDocument where TKey : IEquatable; - - #region Grouping - - /// - /// Groups a collection of documents given a grouping criteria, - /// and returns a list of projected documents. - /// - /// The type representing a Document. - /// The type of the grouping criteria. - /// The type of the projected group. - /// The grouping criteria. - /// The projected group result. - /// The partition key of your document, if any. - List GroupBy( - Expression> groupingCriteria, - Expression, TProjection>> groupProjection, - string partitionKey = null) - where TDocument : IDocument - where TProjection : class, new(); - - /// - /// 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. - /// - /// The type representing a Document. - /// The type of the grouping criteria. - /// The type of the projected group. - /// - /// The grouping criteria. - /// The projected group result. - /// The partition key of your document, if any. - List GroupBy(Expression> filter, - Expression> selector, - Expression, TProjection>> projection, - string partitionKey = null) - where TDocument : IDocument - where TProjection : class, new(); - - #endregion } } diff --git a/MongoDbGenericRepository/Abstractions/IBaseReadOnlyRepository.cs b/MongoDbGenericRepository/Abstractions/IBaseReadOnlyRepository.cs new file mode 100644 index 0000000..32d5c92 --- /dev/null +++ b/MongoDbGenericRepository/Abstractions/IBaseReadOnlyRepository.cs @@ -0,0 +1,410 @@ +using MongoDB.Driver; +using MongoDbGenericRepository.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace MongoDbGenericRepository +{ + 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 + + #region Project TKey + + /// + /// Asynchronously returns a projected document matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type representing the model you want to project to. + /// + /// The projection expression. + /// An optional partition key. + Task ProjectOneAsync(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class; + + /// + /// Returns a projected document matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type representing the model you want to project to. + /// + /// The projection expression. + /// An optional partition key. + TProjection ProjectOne(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class; + + /// + /// Asynchronously returns a list of projected documents matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type representing the model you want to project to. + /// + /// The projection expression. + /// An optional partition key. + Task> ProjectManyAsync(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class; + + /// + /// Asynchronously returns a list of projected documents matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type representing the model you want to project to. + /// + /// The projection expression. + /// An optional partition key. + List ProjectMany(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class; + + #endregion + + #region Group By + + /// + /// 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. + /// + /// The type representing a Document. + /// The type of the grouping criteria. + /// The type of the projected group. + /// A LINQ expression filter. + /// The grouping criteria. + /// The projected group result. + /// The partition key of your document, if any. + List GroupBy( + Expression> groupingCriteria, + Expression, TProjection>> groupProjection, + string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class, new(); + + /// + /// 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. + /// + /// The type representing a Document. + /// The type of the grouping criteria. + /// The type of the projected group. + /// A LINQ expression filter. + /// The grouping criteria. + /// The projected group result. + /// The partition key of your document, if any. + List GroupBy( + Expression> filter, + Expression> groupingCriteria, + Expression, TProjection>> groupProjection, + string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class, new(); + + #endregion Group By + } +} diff --git a/MongoDbGenericRepository/Abstractions/IKeyTypedReadOnlyMongoRepository.cs b/MongoDbGenericRepository/Abstractions/IKeyTypedReadOnlyMongoRepository.cs index 2b73f76..847a2a4 100644 --- a/MongoDbGenericRepository/Abstractions/IKeyTypedReadOnlyMongoRepository.cs +++ b/MongoDbGenericRepository/Abstractions/IKeyTypedReadOnlyMongoRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; using MongoDB.Driver; @@ -241,5 +242,98 @@ namespace MongoDbGenericRepository where TDocument : IDocument; #endregion Maths + + #region Project + + /// + /// Asynchronously returns a projected document matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type representing the model you want to project to. + /// A LINQ expression filter. + /// The projection expression. + /// An optional partition key. + Task ProjectOneAsync(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TProjection : class; + + /// + /// Returns a projected document matching the filter condition. + /// + /// The type representing a Document. + /// The type representing the model you want to project to. + /// A LINQ expression filter. + /// The projection expression. + /// An optional partition key. + TProjection ProjectOne(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TProjection : class; + + /// + /// Asynchronously returns a list of projected documents matching the filter condition. + /// + /// The type representing a Document. + /// The type representing the model you want to project to. + /// A LINQ expression filter. + /// The projection expression. + /// An optional partition key. + Task> ProjectManyAsync(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TProjection : class; + + /// + /// Asynchronously returns a list of projected documents matching the filter condition. + /// + /// The type representing a Document. + /// The type representing the model you want to project to. + /// A LINQ expression filter. + /// The projection expression. + /// An optional partition key. + List ProjectMany(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TProjection : class; + + #endregion Project + + #region Group By + + /// + /// 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. + /// + /// The type representing a Document. + /// The type of the grouping criteria. + /// The type of the projected group. + /// The grouping criteria. + /// The projected group result. + /// The partition key of your document, if any. + List GroupBy( + Expression> groupingCriteria, + Expression, TProjection>> groupProjection, + string partitionKey = null) + where TDocument : IDocument + where TProjection : class, new(); + + /// + /// 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. + /// + /// The type representing a Document. + /// The type of the grouping criteria. + /// The type of the projected group. + /// A LINQ expression filter. + /// The grouping criteria. + /// The projected group result. + /// The partition key of your document, if any. + List GroupBy( + Expression> filter, + Expression> groupingCriteria, + Expression, TProjection>> groupProjection, + string partitionKey = null) + where TDocument : IDocument + where TProjection : class, new(); + + #endregion Group By } } \ No newline at end of file diff --git a/MongoDbGenericRepository/Abstractions/IMongoDbCollectionIndexRepository.cs b/MongoDbGenericRepository/Abstractions/IMongoDbCollectionIndexRepository.cs deleted file mode 100644 index 3fa09b9..0000000 --- a/MongoDbGenericRepository/Abstractions/IMongoDbCollectionIndexRepository.cs +++ /dev/null @@ -1,96 +0,0 @@ -using MongoDbGenericRepository.Models; -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Threading.Tasks; - -namespace MongoDbGenericRepository -{ - /// - /// The repository interface for managing indexes - /// - public interface IMongoDbCollectionIndexRepository : IBaseMongoDbIndexRepository - { - /// - /// Create a text index on the given field. - /// IndexCreationOptions can be supplied to further specify - /// how the creation should be done. - /// - /// The type representing a Document. - /// The field we want to index. - /// Options for creating an index. - /// An optional partition key. - /// The result of the create index operation. - Task CreateTextIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument; - - /// - /// Creates an index on the given field in ascending order. - /// IndexCreationOptions can be supplied to further specify - /// how the creation should be done. - /// - /// The type representing a Document. - /// The field we want to index. - /// Options for creating an index. - /// An optional partition key. - /// The result of the create index operation. - Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument; - - /// - /// Creates an index on the given field in descending order. - /// IndexCreationOptions can be supplied to further specify - /// how the creation should be done. - /// - /// The type representing a Document. - /// The field we want to index. - /// Options for creating an index. - /// An optional partition key. - /// A string containing the result of the operation. - Task CreateDescendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument; - - /// - /// Creates a hashed index on the given field. - /// IndexCreationOptions can be supplied to further specify - /// how the creation should be done. - /// - /// The type representing a Document. - /// The field we want to index. - /// Options for creating an index. - /// An optional partition key. - /// A string containing the result of the operation. - Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument; - - /// - /// Creates a combined text index. - /// IndexCreationOptions can be supplied to further specify - /// how the creation should be done. - /// - /// The type representing a Document. - /// The fields we want to index. - /// Options for creating an index. - /// An optional partition key. - /// The result of the create index operation. - Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument; - - /// - /// Drops the index given a field name - /// - /// The type representing a Document. - /// The name of the index - /// An optional partition key - Task DropIndexAsync(string indexName, string partitionKey = null) - where TDocument : IDocument; - - /// - /// Returns the names of the indexes present on a collection. - /// - /// The type representing a Document. - /// An optional partition key - /// A list containing the names of the indexes on on the concerned collection. - Task> GetIndexesNamesAsync(string partitionKey = null) - where TDocument : IDocument; - } -} diff --git a/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs b/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs index a5e295e..61d6a44 100644 --- a/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs +++ b/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs @@ -1,4 +1,8 @@ -using System; +using MongoDbGenericRepository.Models; +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Threading.Tasks; namespace MongoDbGenericRepository { @@ -7,5 +11,6 @@ namespace MongoDbGenericRepository /// public interface IReadOnlyMongoRepository : IBaseReadOnlyRepository, IKeyTypedReadOnlyMongoRepository { + } } diff --git a/MongoDbGenericRepository/BaseMongoDbRepository.IndexManagement.cs b/MongoDbGenericRepository/BaseMongoDbRepository.IndexManagement.cs deleted file mode 100644 index b82294f..0000000 --- a/MongoDbGenericRepository/BaseMongoDbRepository.IndexManagement.cs +++ /dev/null @@ -1,72 +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 -{ - /// - /// 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 - { - #region Index Management - - /// - public async Task CreateTextIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument - { - return await CreateTextIndexAsync(field, indexCreationOptions, partitionKey); - } - - /// - public async Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument - { - return await CreateAscendingIndexAsync(field, indexCreationOptions, partitionKey); - } - - /// - public async Task CreateDescendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument - { - return await CreateDescendingIndexAsync(field, indexCreationOptions, partitionKey); - } - - - /// - public async Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument - { - return await CreateHashedIndexAsync(field, indexCreationOptions, partitionKey); - } - - /// - public async Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument - { - return await CreateCombinedTextIndexAsync(fields, indexCreationOptions, partitionKey); - } - - - /// - public async Task DropIndexAsync(string indexName, string partitionKey = null) - where TDocument : IDocument - { - await DropIndexAsync(indexName, partitionKey); - } - - /// - public async Task> GetIndexesNamesAsync(string partitionKey = null) - where TDocument : IDocument - { - return await GetIndexesNamesAsync(partitionKey); - } - - #endregion Index Management - - - } -} \ No newline at end of file diff --git a/MongoDbGenericRepository/BaseMongoDbRepository.cs b/MongoDbGenericRepository/BaseMongoDbRepository.cs deleted file mode 100644 index 2fd1ad2..0000000 --- a/MongoDbGenericRepository/BaseMongoDbRepository.cs +++ /dev/null @@ -1,1037 +0,0 @@ -using MongoDB.Driver; -using MongoDbGenericRepository.DataAccess.Create; -using MongoDbGenericRepository.DataAccess.Update; -using MongoDbGenericRepository.Models; -using MongoDbGenericRepository.Utils; -using System; -using System.Collections.Generic; -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 BaseMongoRepository : ReadOnlyMongoRepository, IBaseMongoRepository - { - private object _initLock; - private MongoDbCreator _mongoDbCreator; - protected MongoDbCreator MongoDbCreator - { - get - { - if (_mongoDbCreator != null) { return _mongoDbCreator; } - - lock (_initLock) - { - if (_mongoDbCreator == null) - { - _mongoDbCreator = new MongoDbCreator(MongoDbContext); - } - } - - return _mongoDbCreator; - } - } - - private MongoDbUpdater _mongoDbUpdater; - protected MongoDbUpdater MongoDbUpdater - { - get - { - if (_mongoDbUpdater != null) { return _mongoDbUpdater; } - - lock (_initLock) - { - if (_mongoDbUpdater == null) - { - _mongoDbUpdater = new MongoDbUpdater(MongoDbContext); - } - } - - return _mongoDbUpdater; - } - } - - /// - /// 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 BaseMongoRepository(string connectionString, string databaseName = null) : base(connectionString, databaseName) - { - } - - /// - /// The contructor taking a . - /// - /// A mongodb context implementing - protected BaseMongoRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext) - { - } - - /// - /// The contructor taking a . - /// - /// A mongodb context implementing - protected BaseMongoRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase) - { - } - - #region Create TKey - - /// - /// Asynchronously adds a document to the collection. - /// Populates the Id and AddedAtUtc fields if necessary. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document you want to add. - public virtual async Task AddOneAsync(TDocument document) - where TDocument : IDocument - where TKey : IEquatable - { - await MongoDbCreator.AddOneAsync(document); - } - - /// - /// Adds a document to the collection. - /// Populates the Id and AddedAtUtc fields if necessary. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document you want to add. - public virtual void AddOne(TDocument document) - where TDocument : IDocument - where TKey : IEquatable - { - MongoDbCreator.AddOne(document); - } - - /// - /// Asynchronously adds a list of documents to the collection. - /// Populates the Id and AddedAtUtc fields if necessary. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The documents you want to add. - public virtual async Task AddManyAsync(IEnumerable documents) - where TDocument : IDocument - where TKey : IEquatable - { - await MongoDbCreator.AddManyAsync(documents); - } - - /// - /// Adds a list of documents to the collection. - /// Populates the Id and AddedAtUtc fields if necessary. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The documents you want to add. - public virtual void AddMany(IEnumerable documents) - where TDocument : IDocument - where TKey : IEquatable - { - MongoDbCreator.AddMany(documents); - } - - #endregion - - #region Update - - /// - /// Asynchronously Updates a document. - /// - /// The type representing a Document. - /// The document with the modifications you want to persist. - public virtual async Task UpdateOneAsync(TDocument modifiedDocument) where TDocument : IDocument - { - return await MongoDbUpdater.UpdateOneAsync(modifiedDocument); - } - - /// - /// Updates a document. - /// - /// The type representing a Document. - /// The document with the modifications you want to persist. - public virtual bool UpdateOne(TDocument modifiedDocument) where TDocument : IDocument - { - return MongoDbUpdater.UpdateOne(modifiedDocument); - } - - /// - /// Takes a document you want to modify and applies the update you have defined in MongoDb. - /// - /// The type representing a Document. - /// The document you want to modify. - /// The update definition for the document. - public virtual async Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) - where TDocument : IDocument - { - return await MongoDbUpdater.UpdateOneAsync(documentToModify, update); - - } - - /// - /// Takes a document you want to modify and applies the update you have defined in MongoDb. - /// - /// The type representing a Document. - /// The document you want to modify. - /// The update definition for the document. - public virtual bool UpdateOne(TDocument documentToModify, UpdateDefinition update) - where TDocument : IDocument - { - return MongoDbUpdater.UpdateOne(documentToModify, update); - } - - /// - /// Updates the property field with the given value update a property field in entities. - /// - /// The type representing a Document. - /// The type of the field. - /// The document you want to modify. - /// The field selector. - /// The new value of the property field. - public virtual bool UpdateOne(TDocument documentToModify, Expression> field, TField value) - where TDocument : IDocument - { - return MongoDbUpdater.UpdateOne(documentToModify, field, value); - } - - /// - /// Updates the property field with the given value update a property field in entities. - /// - /// The type representing a Document. - /// The type of the field. - /// The document you want to modify. - /// The field selector. - /// The new value of the property field. - public virtual async Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) - where TDocument : IDocument - { - return await MongoDbUpdater.UpdateOneAsync(documentToModify, field, value); - } - - /// - /// Updates the property field with the given value update a property field in entities. - /// - /// The type representing a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The value of the partition key. - public virtual bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument - { - return MongoDbUpdater.UpdateOne(filter, field, value, partitionKey); - } - - /// - /// For the entity selected by the filter, updates the property field with the given value. - /// - /// The type representing a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The partition key for the document. - public virtual bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument - { - return MongoDbUpdater.UpdateOne(filter, field, value, partitionKey); - } - - /// - /// Updates the property field with the given value update a property field in entities. - /// - /// The type representing a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The value of the partition key. - public virtual async Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument - { - return await MongoDbUpdater.UpdateOneAsync(filter, field, value, partitionKey); - } - - /// - /// For the entity selected by the filter, updates the property field with the given value. - /// - /// The type representing a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The partition key for the document. - public virtual async Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument - { - return await MongoDbUpdater.UpdateOneAsync(filter, field, value, partitionKey); - } - - - #endregion Update - - #region Update TKey - - /// - /// Asynchronously Updates a document. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document with the modifications you want to persist. - public virtual async Task UpdateOneAsync(TDocument modifiedDocument) - where TDocument : IDocument - where TKey : IEquatable - { - return await MongoDbUpdater.UpdateOneAsync(modifiedDocument); - } - - /// - /// Updates a document. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document with the modifications you want to persist. - public virtual bool UpdateOne(TDocument modifiedDocument) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbUpdater.UpdateOne(modifiedDocument); - } - - /// - /// Takes a document you want to modify and applies the update you have defined in MongoDb. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document you want to modify. - /// The update definition for the document. - public virtual async Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) - where TDocument : IDocument - where TKey : IEquatable - { - return await MongoDbUpdater.UpdateOneAsync(documentToModify, update); - } - - /// - /// Takes a document you want to modify and applies the update you have defined in MongoDb. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document you want to modify. - /// The update definition for the document. - public virtual bool UpdateOne(TDocument documentToModify, UpdateDefinition update) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbUpdater.UpdateOne(documentToModify, update); - } - - /// - /// Updates the property field with the given value update a property field in entities. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type of the field. - /// The document you want to modify. - /// The field selector. - /// The new value of the property field. - public virtual bool UpdateOne(TDocument documentToModify, Expression> field, TField value) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbUpdater.UpdateOne(documentToModify, field, value); - } - - /// - /// Updates the property field with the given value update a property field in entities. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type of the field. - /// The document you want to modify. - /// The field selector. - /// The new value of the property field. - public virtual async Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) - where TDocument : IDocument - where TKey : IEquatable - { - return await MongoDbUpdater.UpdateOneAsync(documentToModify, field, value); - } - - /// - /// Updates the property field with the given value. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The value of the partition key. - public virtual bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbUpdater.UpdateOne(filter, field, value, partitionKey); - } - - /// - /// For the entity selected by the filter, updates the property field with the given value. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The partition key for the document. - public virtual bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbUpdater.UpdateOne(filter, field, value, partitionKey); - } - - /// - /// Updates the property field with the given value update a property field in entities. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The value of the partition key. - public virtual async Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return await MongoDbUpdater.UpdateOneAsync(filter, field, value, partitionKey); - } - - /// - /// For the entity selected by the filter, updates the property field with the given value. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type of the field. - /// The document filter. - /// The field selector. - /// The new value of the property field. - /// The partition key for the document. - public virtual async Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return await UpdateOneAsync(Builders.Filter.Where(filter), field, value, partitionKey); - } - - #endregion Update - - #region Delete - - /// - /// Asynchronously deletes a document. - /// - /// The type representing a Document. - /// The document you want to delete. - /// The number of documents deleted. - public virtual async Task DeleteOneAsync(TDocument document) where TDocument : IDocument - { - return await DeleteOneAsync(document); - } - - /// - /// Deletes a document. - /// - /// The type representing a Document. - /// The document you want to delete. - /// The number of documents deleted. - public virtual long DeleteOne(TDocument document) where TDocument : IDocument - { - return DeleteOne(document); - } - - /// - /// Deletes a document matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - public virtual long DeleteOne(Expression> filter, string partitionKey = null) where TDocument : IDocument - { - return DeleteOne(filter, partitionKey); - } - - /// - /// Asynchronously deletes a document matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - public virtual async Task DeleteOneAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument - { - return await DeleteOneAsync(filter, partitionKey); - } - - /// - /// Asynchronously deletes the documents matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - public virtual async Task DeleteManyAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument - { - return (await HandlePartitioned(partitionKey).DeleteManyAsync(filter)).DeletedCount; - } - - /// - /// Asynchronously deletes a list of documents. - /// - /// The type representing a Document. - /// The list of documents to delete. - /// The number of documents deleted. - public virtual async Task DeleteManyAsync(IEnumerable documents) where TDocument : IDocument - { - return await DeleteManyAsync(documents); - } - - /// - /// Deletes a list of documents. - /// - /// The type representing a Document. - /// The list of documents to delete. - /// The number of documents deleted. - public virtual long DeleteMany(IEnumerable documents) where TDocument : IDocument - { - return DeleteMany(documents); - } - - /// - /// Deletes the documents matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - public virtual long DeleteMany(Expression> filter, string partitionKey = null) where TDocument : IDocument - { - return HandlePartitioned(partitionKey).DeleteMany(filter).DeletedCount; - } - - #endregion Delete - - #region Delete TKey - - /// - /// Deletes a document. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document you want to delete. - /// The number of documents deleted. - public virtual long DeleteOne(TDocument document) - where TDocument : IDocument - where TKey : IEquatable - { - var filter = Builders.Filter.Eq("Id", document.Id); - return HandlePartitioned(document).DeleteOne(filter).DeletedCount; - } - - /// - /// Asynchronously deletes a document matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The document you want to delete. - /// The number of documents deleted. - public virtual async Task DeleteOneAsync(TDocument document) - where TDocument : IDocument - where TKey : IEquatable - { - var filter = Builders.Filter.Eq("Id", document.Id); - return (await HandlePartitioned(document).DeleteOneAsync(filter)).DeletedCount; - } - - /// - /// Deletes a document matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - public virtual long DeleteOne(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return HandlePartitioned(partitionKey).DeleteOne(filter).DeletedCount; - } - - /// - /// Asynchronously deletes a document matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - public virtual async Task DeleteOneAsync(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return (await HandlePartitioned(partitionKey).DeleteOneAsync(filter)).DeletedCount; - } - - /// - /// Asynchronously deletes the documents matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - public virtual async Task DeleteManyAsync(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return (await HandlePartitioned(partitionKey).DeleteManyAsync(filter)).DeletedCount; - } - - /// - /// Asynchronously deletes a list of documents. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The list of documents to delete. - /// The number of documents deleted. - public virtual async Task DeleteManyAsync(IEnumerable documents) - where TDocument : IDocument - where TKey : IEquatable - { - 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(group.FirstOrDefault()).DeleteManyAsync(x => groupIdsTodelete.Contains(x.Id))).DeletedCount; - } - return deleteCount; - } - else - { - var idsTodelete = documents.Select(e => e.Id).ToArray(); - return (await HandlePartitioned(documents.FirstOrDefault()).DeleteManyAsync(x => idsTodelete.Contains(x.Id))).DeletedCount; - } - } - - /// - /// Deletes a list of documents. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The list of documents to delete. - /// The number of documents deleted. - public virtual long DeleteMany(IEnumerable documents) - where TDocument : IDocument - where TKey : IEquatable - { - 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(group.FirstOrDefault()).DeleteMany(x => groupIdsTodelete.Contains(x.Id))).DeletedCount; - } - return deleteCount; - } - else - { - var idsTodelete = documents.Select(e => e.Id).ToArray(); - return (HandlePartitioned(documents.FirstOrDefault()).DeleteMany(x => idsTodelete.Contains(x.Id))).DeletedCount; - } - } - - /// - /// Deletes the documents matching the condition of the LINQ expression filter. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// An optional partition key. - /// The number of documents deleted. - public virtual long DeleteMany(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return HandlePartitioned(partitionKey).DeleteMany(filter).DeletedCount; - } - - #endregion - - #region Project - - /// - /// Asynchronously returns a projected document matching the filter condition. - /// - /// The type representing a Document. - /// The type representing the model you want to project to. - /// A LINQ expression filter. - /// The projection expression. - /// An optional partition key. - public virtual async Task ProjectOneAsync(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TProjection : class - { - return await HandlePartitioned(partitionKey).Find(filter) - .Project(projection) - .FirstOrDefaultAsync(); - } - - /// - /// Asynchronously returns a projected document matching the filter condition. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type representing the model you want to project to. - /// A LINQ expression filter. - /// The projection expression. - /// An optional partition key. - public virtual async Task ProjectOneAsync(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - where TProjection : class - { - return await HandlePartitioned(partitionKey).Find(filter) - .Project(projection) - .FirstOrDefaultAsync(); - } - - /// - /// Returns a projected document matching the filter condition. - /// - /// The type representing a Document. - /// The type representing the model you want to project to. - /// A LINQ expression filter. - /// The projection expression. - /// An optional partition key. - public virtual TProjection ProjectOne(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TProjection : class - { - return HandlePartitioned(partitionKey).Find(filter) - .Project(projection) - .FirstOrDefault(); - } - - /// - /// Returns a projected document matching the filter condition. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type representing the model you want to project to. - /// A LINQ expression filter. - /// The projection expression. - /// An optional partition key. - public virtual TProjection ProjectOne(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - where TProjection : class - { - return HandlePartitioned(partitionKey).Find(filter) - .Project(projection) - .FirstOrDefault(); - } - - /// - /// Asynchronously returns a list of projected documents matching the filter condition. - /// - /// The type representing a Document. - /// The type representing the model you want to project to. - /// A LINQ expression filter. - /// The projection expression. - /// An optional partition key. - public virtual async Task> ProjectManyAsync(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TProjection : class - { - return await HandlePartitioned(partitionKey).Find(filter) - .Project(projection) - .ToListAsync(); - } - - /// - /// Asynchronously returns a list of projected documents matching the filter condition. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type representing the model you want to project to. - /// A LINQ expression filter. - /// The projection expression. - /// An optional partition key. - public virtual async Task> ProjectManyAsync(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - where TProjection : class - { - return await HandlePartitioned(partitionKey).Find(filter) - .Project(projection) - .ToListAsync(); - } - - /// - /// Asynchronously returns a list of projected documents matching the filter condition. - /// - /// The type representing a Document. - /// The type representing the model you want to project to. - /// A LINQ expression filter. - /// The projection expression. - /// An optional partition key. - public virtual List ProjectMany(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TProjection : class - { - return HandlePartitioned(partitionKey).Find(filter) - .Project(projection) - .ToList(); - } - - /// - /// Asynchronously returns a list of projected documents matching the filter condition. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The type representing the model you want to project to. - /// The document filter. - /// The projection expression. - /// An optional partition key. - public virtual List ProjectMany(Expression> filter, Expression> projection, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - where TProjection : class - { - return HandlePartitioned(partitionKey).Find(filter) - .Project(projection) - .ToList(); - } - - #endregion - - #region Grouping - - /// - /// 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. - /// - /// The type representing a Document. - /// The type of the grouping criteria. - /// The type of the projected group. - /// The grouping criteria. - /// The projected group result. - /// The partition key of your document, if any. - public virtual List GroupBy( - Expression> groupingCriteria, - Expression, TProjection>> groupProjection, - string partitionKey = null) - where TDocument : IDocument - where TProjection : class, new() - { - var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); - return collection.Aggregate() - .Group(groupingCriteria, groupProjection) - .ToList(); - - } - - /// - /// 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. - /// - /// The type representing a Document. - /// The type of the grouping criteria. - /// The type of the projected group. - /// A LINQ expression filter. - /// The grouping criteria. - /// The projected group result. - /// The partition key of your document, if any. - public virtual List GroupBy(Expression> filter, - Expression> selector, - Expression, TProjection>> projection, - string partitionKey = null) - where TDocument : IDocument - where TProjection : class, new() - { - var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); - return collection.Aggregate() - .Match(Builders.Filter.Where(filter)) - .Group(selector, projection) - .ToList(); - } - - - #endregion - - /// - /// Asynchronously returns a paginated list of the documents matching the filter condition. - /// - /// 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> 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(); - } - - /// - /// Asynchronously returns a paginated 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. - /// 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 - where TKey : IEquatable - { - return await HandlePartitioned(partitionKey).Find(filter).Skip(skipNumber).Limit(takeNumber).ToListAsync(); - } - - #region Find And Update - - /// - /// GetAndUpdateOne with filter - /// - /// The type representing a Document. - /// A LINQ expression filter. - /// - /// - /// - public virtual async Task GetAndUpdateOne(FilterDefinition filter, UpdateDefinition update, FindOneAndUpdateOptions options) where TDocument : IDocument - { - return await GetCollection().FindOneAndUpdateAsync(filter, update, options); - } - - /// - /// GetAndUpdateOne with filter - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// A LINQ expression filter. - /// - /// - /// - public virtual async Task GetAndUpdateOne(FilterDefinition filter, UpdateDefinition update, FindOneAndUpdateOptions options) - where TDocument : IDocument - where TKey : IEquatable - { - return await GetCollection().FindOneAndUpdateAsync(filter, update, options); - } - - #endregion Find And Update - - /// - /// Sets the value of the document Id if it is not set already. - /// - /// The document type. - /// The type of the primary key. - /// The document. - protected void FormatDocument(TDocument document) - where TDocument : IDocument - where TKey : IEquatable - { - 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(); - } - } - - /// - /// Sets the value of the document Id if it is not set already. - /// - /// The document type. - /// The document. - protected void FormatDocument(TDocument document) where TDocument : IDocument - { - if (document == null) - { - throw new ArgumentNullException(nameof(document)); - } - if (document.Id == default(Guid)) - { - document.Id = Guid.NewGuid(); - } - } - } -} \ No newline at end of file diff --git a/MongoDbGenericRepository/BaseMongoRepository.Create.cs b/MongoDbGenericRepository/BaseMongoRepository.Create.cs new file mode 100644 index 0000000..5e772de --- /dev/null +++ b/MongoDbGenericRepository/BaseMongoRepository.Create.cs @@ -0,0 +1,186 @@ +using MongoDbGenericRepository.DataAccess.Create; +using MongoDbGenericRepository.Models; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace MongoDbGenericRepository +{ + public interface IBaseMongoRepository_Create : IKeyTypedBaseMongoDbRepository_Create + { + /// + /// Asynchronously adds a document to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to add. + Task AddOneAsync(TDocument document) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Adds a document to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to add. + void AddOne(TDocument document) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Asynchronously adds a list of documents to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The documents you want to add. + Task AddManyAsync(IEnumerable documents) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Adds a list of documents to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The documents you want to add. + void AddMany(IEnumerable documents) + where TDocument : IDocument + where TKey : IEquatable; + } + + /// + /// 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 : IBaseMongoRepository_Create + { + private readonly object _initLock = new object(); + private MongoDbCreator _mongoDbCreator; + protected MongoDbCreator MongoDbCreator + { + get + { + if (_mongoDbCreator != null) { return _mongoDbCreator; } + + lock (_initLock) + { + if (_mongoDbCreator == null) + { + _mongoDbCreator = new MongoDbCreator(MongoDbContext); + } + } + + return _mongoDbCreator; + } + } + + /// + /// Asynchronously adds a document to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to add. + public virtual async Task AddOneAsync(TDocument document) + where TDocument : IDocument + where TKey : IEquatable + { + await MongoDbCreator.AddOneAsync(document); + } + + /// + /// Asynchronously adds a document to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The document you want to add. + public virtual async Task AddOneAsync(TDocument document) + where TDocument : IDocument + { + await MongoDbCreator.AddOneAsync(document); + } + + /// + /// Adds a document to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to add. + public virtual void AddOne(TDocument document) + where TDocument : IDocument + where TKey : IEquatable + { + MongoDbCreator.AddOne(document); + } + + /// + /// Adds a document to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The document you want to add. + public virtual void AddOne(TDocument document) where TDocument : IDocument + { + MongoDbCreator.AddOne(document); + } + + /// + /// Asynchronously adds a list of documents to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The documents you want to add. + public virtual async Task AddManyAsync(IEnumerable documents) + where TDocument : IDocument + where TKey : IEquatable + { + await MongoDbCreator.AddManyAsync(documents); + } + + /// + /// Asynchronously adds a list of documents to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The documents you want to add. + public virtual async Task AddManyAsync(IEnumerable documents) + where TDocument : IDocument + { + await MongoDbCreator.AddManyAsync(documents); + } + + /// + /// Adds a list of documents to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The documents you want to add. + public virtual void AddMany(IEnumerable documents) + where TDocument : IDocument + where TKey : IEquatable + { + MongoDbCreator.AddMany(documents); + } + + /// + /// Adds a list of documents to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The documents you want to add. + public virtual void AddMany(IEnumerable documents) + where TDocument : IDocument + { + MongoDbCreator.AddMany(documents); + } + } + +} diff --git a/MongoDbGenericRepository/BaseMongoRepository.Delete.cs b/MongoDbGenericRepository/BaseMongoRepository.Delete.cs new file mode 100644 index 0000000..5c74794 --- /dev/null +++ b/MongoDbGenericRepository/BaseMongoRepository.Delete.cs @@ -0,0 +1,343 @@ +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 : IKeyTypedBaseMongoDbRepository_Delete + { + /// + /// Deletes a document. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to delete. + /// The number of documents deleted. + long DeleteOne(TDocument document) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Asynchronously deletes a document matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to delete. + /// The number of documents deleted. + Task DeleteOneAsync(TDocument document) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Deletes a document matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + long DeleteOne(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Asynchronously deletes a document matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + Task DeleteOneAsync(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Asynchronously deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + Task DeleteManyAsync(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Asynchronously deletes a list of documents. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The list of documents to delete. + /// The number of documents deleted. + Task DeleteManyAsync(IEnumerable documents) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Deletes a list of documents. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The list of documents to delete. + /// The number of documents deleted. + long DeleteMany(IEnumerable documents) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + long DeleteMany(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + } + + public abstract partial class BaseMongoRepository : IBaseMongoRepository_Delete + { + private MongoDbEraser _mongoDbEraser; + protected MongoDbEraser MongoDbEraser + { + get + { + if (_mongoDbEraser != null) { return _mongoDbEraser; } + + lock (_initLock) + { + if (_mongoDbEraser == null) + { + _mongoDbEraser = new MongoDbEraser(MongoDbContext); + } + } + + return _mongoDbEraser; + } + } + + #region Delete + + /// + /// Asynchronously deletes a document. + /// + /// The type representing a Document. + /// The document you want to delete. + /// The number of documents deleted. + public virtual async Task DeleteOneAsync(TDocument document) where TDocument : IDocument + { + return await MongoDbEraser.DeleteOneAsync(document); + } + + /// + /// Deletes a document. + /// + /// The type representing a Document. + /// The document you want to delete. + /// The number of documents deleted. + public virtual long DeleteOne(TDocument document) where TDocument : IDocument + { + return MongoDbEraser.DeleteOne(document); + } + + /// + /// Deletes a document matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public virtual long DeleteOne(Expression> filter, string partitionKey = null) where TDocument : IDocument + { + return MongoDbEraser.DeleteOne(filter, partitionKey); + } + + /// + /// Asynchronously deletes a document matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public virtual async Task DeleteOneAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument + { + return await MongoDbEraser.DeleteOneAsync(filter, partitionKey); + } + + /// + /// Asynchronously deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public virtual async Task DeleteManyAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument + { + return await MongoDbEraser.DeleteManyAsync(filter, partitionKey); + } + + /// + /// Asynchronously deletes a list of documents. + /// + /// The type representing a Document. + /// The list of documents to delete. + /// The number of documents deleted. + public virtual async Task DeleteManyAsync(IEnumerable documents) where TDocument : IDocument + { + return await DeleteManyAsync(documents); + } + + /// + /// Deletes a list of documents. + /// + /// The type representing a Document. + /// The list of documents to delete. + /// The number of documents deleted. + public virtual long DeleteMany(IEnumerable documents) where TDocument : IDocument + { + return DeleteMany(documents); + } + + /// + /// Deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public virtual long DeleteMany(Expression> filter, string partitionKey = null) where TDocument : IDocument + { + return MongoDbEraser.DeleteMany(filter, partitionKey); + } + + #endregion Delete + + #region Delete TKey + + /// + /// Deletes a document. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to delete. + /// The number of documents deleted. + public virtual long DeleteOne(TDocument document) + where TDocument : IDocument + where TKey : IEquatable + { + return MongoDbEraser.DeleteOne(document); + } + + /// + /// Asynchronously deletes a document matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to delete. + /// The number of documents deleted. + public virtual async Task DeleteOneAsync(TDocument document) + where TDocument : IDocument + where TKey : IEquatable + { + return await MongoDbEraser.DeleteOneAsync(document); + } + + /// + /// Deletes a document matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public virtual long DeleteOne(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return MongoDbEraser.DeleteOne(filter, partitionKey); + } + + /// + /// Asynchronously deletes a document matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public virtual async Task DeleteOneAsync(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return await MongoDbEraser.DeleteOneAsync(filter, partitionKey); + } + + /// + /// Asynchronously deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public virtual async Task DeleteManyAsync(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return await MongoDbEraser.DeleteManyAsync(filter, partitionKey); + } + + /// + /// Asynchronously deletes a list of documents. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The list of documents to delete. + /// The number of documents deleted. + public virtual async Task DeleteManyAsync(IEnumerable documents) + where TDocument : IDocument + where TKey : IEquatable + { + return await MongoDbEraser.DeleteManyAsync(documents); + } + + /// + /// Deletes a list of documents. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The list of documents to delete. + /// The number of documents deleted. + public virtual long DeleteMany(IEnumerable documents) + where TDocument : IDocument + where TKey : IEquatable + { + return MongoDbEraser.DeleteMany(documents); + } + + /// + /// Deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public virtual long DeleteMany(Expression> filter, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return MongoDbEraser.DeleteMany(filter, partitionKey); + } + + #endregion + + } +} diff --git a/MongoDbGenericRepository/BaseMongoRepository.Index.cs b/MongoDbGenericRepository/BaseMongoRepository.Index.cs new file mode 100644 index 0000000..d973a16 --- /dev/null +++ b/MongoDbGenericRepository/BaseMongoRepository.Index.cs @@ -0,0 +1,319 @@ +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 : IKeyTypedBaseMongoDbRepository_Index + { + /// + /// Returns the names of the indexes present on a collection. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// An optional partition key + /// A list containing the names of the indexes on on the concerned collection. + Task> GetIndexesNamesAsync(string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Create a text index on the given field. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + Task CreateTextIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Creates an index on the given field in ascending order. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Creates an index on the given field in descending order. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + Task CreateDescendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Creates a hashed index on the given field. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Creates a combined text index. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The fields we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Drops the index given a field name + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The name of the index + /// An optional partition key + Task DropIndexAsync(string indexName, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + } + /// + /// 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 : IBaseMongoRepository_Index + { + private MongoDbIndexHandler _mongoDbIndexHandler; + protected MongoDbIndexHandler MongoDbIndexHandler + { + get + { + if (_mongoDbIndexHandler != null) { return _mongoDbIndexHandler; } + + lock (_initLock) + { + if (_mongoDbIndexHandler == null) + { + _mongoDbIndexHandler = new MongoDbIndexHandler(MongoDbContext); + } + } + return _mongoDbIndexHandler; + } + } + + /// + /// Returns the names of the indexes present on a collection. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// An optional partition key + /// A list containing the names of the indexes on on the concerned collection. + public async Task> GetIndexesNamesAsync(string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbIndexHandler.GetIndexesNamesAsync(partitionKey); + } + + /// + /// Returns the names of the indexes present on a collection. + /// + /// The type representing a Document. + /// An optional partition key + /// A list containing the names of the indexes on on the concerned collection. + public async virtual Task> GetIndexesNamesAsync(string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return await MongoDbIndexHandler.GetIndexesNamesAsync(partitionKey); + } + + /// + /// Create a text index on the given field. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + public async Task CreateTextIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbIndexHandler.CreateTextIndexAsync(field, indexCreationOptions, partitionKey); + } + + /// + /// Create a text index on the given field. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + public async virtual Task CreateTextIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return await MongoDbIndexHandler.CreateTextIndexAsync(field, indexCreationOptions, partitionKey); + } + + /// + /// Creates an index on the given field in ascending order. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + public async Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbIndexHandler.CreateAscendingIndexAsync(field, indexCreationOptions, partitionKey); + } + + /// + /// Creates an index on the given field in ascending order. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + public async virtual Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return await MongoDbIndexHandler.CreateAscendingIndexAsync(field, indexCreationOptions, partitionKey); + } + + /// + /// Creates an index on the given field in descending order. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + public async Task CreateDescendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbIndexHandler.CreateDescendingIndexAsync(field, indexCreationOptions, partitionKey); + } + + /// + public async virtual Task CreateDescendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return await MongoDbIndexHandler.CreateDescendingIndexAsync(field, indexCreationOptions, partitionKey); + } + + /// + /// Creates a hashed index on the given field. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + public async Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbIndexHandler.CreateHashedIndexAsync(field, indexCreationOptions, partitionKey); + } + + /// + public async virtual Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return await MongoDbIndexHandler.CreateHashedIndexAsync(field, indexCreationOptions, partitionKey); + } + + /// + /// Creates a combined text index. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The fields we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + public async Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbIndexHandler.CreateCombinedTextIndexAsync(fields, indexCreationOptions, partitionKey); + } + + /// + public async virtual Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return await MongoDbIndexHandler.CreateCombinedTextIndexAsync(fields, indexCreationOptions, partitionKey); + } + + /// + /// Drops the index given a field name + /// + /// The type representing a Document. + /// The name of the index + /// An optional partition key + public async Task DropIndexAsync(string indexName, string partitionKey = null) + where TDocument : IDocument + { + await MongoDbIndexHandler.DropIndexAsync(partitionKey); + } + + /// + public async virtual Task DropIndexAsync(string indexName, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + await MongoDbIndexHandler.DropIndexAsync(partitionKey); + } + } +} \ No newline at end of file diff --git a/MongoDbGenericRepository/BaseMongoRepository.Main.cs b/MongoDbGenericRepository/BaseMongoRepository.Main.cs new file mode 100644 index 0000000..b7df9cc --- /dev/null +++ b/MongoDbGenericRepository/BaseMongoRepository.Main.cs @@ -0,0 +1,211 @@ +using MongoDB.Driver; +using MongoDbGenericRepository.Models; +using MongoDbGenericRepository.Utils; +using System; +using System.Collections.Generic; +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 BaseMongoRepository : ReadOnlyMongoRepository, IBaseMongoRepository + { + /// + /// 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 BaseMongoRepository(string connectionString, string databaseName = null) : base(connectionString, databaseName) + { + } + + /// + /// The contructor taking a . + /// + /// A mongodb context implementing + protected BaseMongoRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext) + { + } + + /// + /// The contructor taking a . + /// + /// A mongodb context implementing + protected BaseMongoRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase) + { + } + + + /// + /// Asynchronously returns a paginated list of the documents matching the filter condition. + /// + /// 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> 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(); + } + + /// + /// Asynchronously returns a paginated 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. + /// 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 + where TKey : IEquatable + { + return await HandlePartitioned(partitionKey).Find(filter).Skip(skipNumber).Limit(takeNumber).ToListAsync(); + } + + #region Find And Update + + /// + /// GetAndUpdateOne with filter + /// + /// The type representing a Document. + /// A LINQ expression filter. + /// + /// + /// + public virtual async Task GetAndUpdateOne(FilterDefinition filter, UpdateDefinition update, FindOneAndUpdateOptions options) where TDocument : IDocument + { + return await GetCollection().FindOneAndUpdateAsync(filter, update, options); + } + + /// + /// GetAndUpdateOne with filter + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// + /// + /// + public virtual async Task GetAndUpdateOne(FilterDefinition filter, UpdateDefinition update, FindOneAndUpdateOptions options) + where TDocument : IDocument + where TKey : IEquatable + { + return await GetCollection().FindOneAndUpdateAsync(filter, update, options); + } + + #endregion Find And Update + + /// + /// Sets the value of the document Id if it is not set already. + /// + /// The document type. + /// The type of the primary key. + /// The document. + protected void FormatDocument(TDocument document) + where TDocument : IDocument + where TKey : IEquatable + { + 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(); + } + } + + /// + /// Sets the value of the document Id if it is not set already. + /// + /// The document type. + /// The document. + protected void FormatDocument(TDocument document) where TDocument : IDocument + { + if (document == null) + { + throw new ArgumentNullException(nameof(document)); + } + if (document.Id == default(Guid)) + { + document.Id = Guid.NewGuid(); + } + } + + /// + /// Gets a collections for a potentially partitioned document type. + /// + /// The document type. + /// The collection partition key. + /// + protected virtual IMongoCollection HandlePartitioned(string partitionKey) + where TDocument : IDocument + { + if (!string.IsNullOrEmpty(partitionKey)) + { + return GetCollection(partitionKey); + } + return GetCollection(); + } + + /// + /// Gets a collections for the type TDocument with a partition key. + /// + /// The document type. + /// The collection partition key. + /// + protected virtual IMongoCollection GetCollection(string partitionKey = null) + where TDocument : IDocument + { + return MongoDbContext.GetCollection(partitionKey); + } + } +} \ No newline at end of file diff --git a/MongoDbGenericRepository/BaseMongoRepository.Update.cs b/MongoDbGenericRepository/BaseMongoRepository.Update.cs new file mode 100644 index 0000000..beea2e1 --- /dev/null +++ b/MongoDbGenericRepository/BaseMongoRepository.Update.cs @@ -0,0 +1,457 @@ +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 : IKeyTypedBaseMongoDbRepository_Update + { + /// + /// Asynchronously Updates a document. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document with the modifications you want to persist. + Task UpdateOneAsync(TDocument modifiedDocument) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Updates a document. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document with the modifications you want to persist. + bool UpdateOne(TDocument modifiedDocument) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Takes a document you want to modify and applies the update you have defined in MongoDb. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to modify. + /// The update definition for the document. + Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Takes a document you want to modify and applies the update you have defined in MongoDb. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to modify. + /// The update definition for the document. + bool UpdateOne(TDocument documentToModify, UpdateDefinition update) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// For the entity selected by the filter, updates the property field with the given value.. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The partition key for the document. + bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Updates the property field with the given value update a property field in entities. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document you want to modify. + /// The field selector. + /// The new value of the property field. + Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// For the entity selected by the filter, updates the property field with the given value. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The partition key for the document. + Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Updates the property field with the given value update a property field in entities. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document you want to modify. + /// The field selector. + /// The new value of the property field. + bool UpdateOne(TDocument documentToModify, Expression> field, TField value) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Updates the property field with the given value update a property field in entities. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The value of the partition key. + Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + + /// + /// Updates the property field with the given value update a property field in entities. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The value of the partition key. + bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable; + } + /// + /// 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 : IBaseMongoRepository_Update + { + private MongoDbUpdater _mongoDbUpdater; + protected MongoDbUpdater MongoDbUpdater + { + get + { + if (_mongoDbUpdater != null) { return _mongoDbUpdater; } + + lock (_initLock) + { + if (_mongoDbUpdater == null) + { + _mongoDbUpdater = new MongoDbUpdater(MongoDbContext); + } + } + + return _mongoDbUpdater; + } + } + + #region Update + + /// + /// Asynchronously Updates a document. + /// + /// The type representing a Document. + /// The document with the modifications you want to persist. + public virtual async Task UpdateOneAsync(TDocument modifiedDocument) where TDocument : IDocument + { + return await MongoDbUpdater.UpdateOneAsync(modifiedDocument); + } + + /// + /// Updates a document. + /// + /// The type representing a Document. + /// The document with the modifications you want to persist. + public virtual bool UpdateOne(TDocument modifiedDocument) where TDocument : IDocument + { + return MongoDbUpdater.UpdateOne(modifiedDocument); + } + + /// + /// Takes a document you want to modify and applies the update you have defined in MongoDb. + /// + /// The type representing a Document. + /// The document you want to modify. + /// The update definition for the document. + public virtual async Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) + where TDocument : IDocument + { + return await MongoDbUpdater.UpdateOneAsync(documentToModify, update); + + } + + /// + /// Takes a document you want to modify and applies the update you have defined in MongoDb. + /// + /// The type representing a Document. + /// The document you want to modify. + /// The update definition for the document. + public virtual bool UpdateOne(TDocument documentToModify, UpdateDefinition update) + where TDocument : IDocument + { + return MongoDbUpdater.UpdateOne(documentToModify, update); + } + + /// + /// Updates the property field with the given value update a property field in entities. + /// + /// The type representing a Document. + /// The type of the field. + /// The document you want to modify. + /// The field selector. + /// The new value of the property field. + public virtual bool UpdateOne(TDocument documentToModify, Expression> field, TField value) + where TDocument : IDocument + { + return MongoDbUpdater.UpdateOne(documentToModify, field, value); + } + + /// + /// Updates the property field with the given value update a property field in entities. + /// + /// The type representing a Document. + /// The type of the field. + /// The document you want to modify. + /// The field selector. + /// The new value of the property field. + public virtual async Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) + where TDocument : IDocument + { + return await MongoDbUpdater.UpdateOneAsync(documentToModify, field, value); + } + + /// + /// Updates the property field with the given value update a property field in entities. + /// + /// The type representing a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The value of the partition key. + public virtual bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + { + return MongoDbUpdater.UpdateOne(filter, field, value, partitionKey); + } + + /// + /// For the entity selected by the filter, updates the property field with the given value. + /// + /// The type representing a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The partition key for the document. + public virtual bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + { + return MongoDbUpdater.UpdateOne(filter, field, value, partitionKey); + } + + /// + /// Updates the property field with the given value update a property field in entities. + /// + /// The type representing a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The value of the partition key. + public virtual async Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbUpdater.UpdateOneAsync(filter, field, value, partitionKey); + } + + /// + /// For the entity selected by the filter, updates the property field with the given value. + /// + /// The type representing a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The partition key for the document. + public virtual async Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbUpdater.UpdateOneAsync(filter, field, value, partitionKey); + } + + #endregion Update + + #region Update TKey + + /// + /// Asynchronously Updates a document. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document with the modifications you want to persist. + public virtual async Task UpdateOneAsync(TDocument modifiedDocument) + where TDocument : IDocument + where TKey : IEquatable + { + return await MongoDbUpdater.UpdateOneAsync(modifiedDocument); + } + + /// + /// Updates a document. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document with the modifications you want to persist. + public virtual bool UpdateOne(TDocument modifiedDocument) + where TDocument : IDocument + where TKey : IEquatable + { + return MongoDbUpdater.UpdateOne(modifiedDocument); + } + + /// + /// Takes a document you want to modify and applies the update you have defined in MongoDb. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to modify. + /// The update definition for the document. + public virtual async Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) + where TDocument : IDocument + where TKey : IEquatable + { + return await MongoDbUpdater.UpdateOneAsync(documentToModify, update); + } + + /// + /// Takes a document you want to modify and applies the update you have defined in MongoDb. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to modify. + /// The update definition for the document. + public virtual bool UpdateOne(TDocument documentToModify, UpdateDefinition update) + where TDocument : IDocument + where TKey : IEquatable + { + return MongoDbUpdater.UpdateOne(documentToModify, update); + } + + /// + /// Updates the property field with the given value update a property field in entities. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document you want to modify. + /// The field selector. + /// The new value of the property field. + public virtual bool UpdateOne(TDocument documentToModify, Expression> field, TField value) + where TDocument : IDocument + where TKey : IEquatable + { + return MongoDbUpdater.UpdateOne(documentToModify, field, value); + } + + /// + /// Updates the property field with the given value update a property field in entities. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document you want to modify. + /// The field selector. + /// The new value of the property field. + public virtual async Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) + where TDocument : IDocument + where TKey : IEquatable + { + return await MongoDbUpdater.UpdateOneAsync(documentToModify, field, value); + } + + /// + /// Updates the property field with the given value. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The value of the partition key. + public virtual bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return MongoDbUpdater.UpdateOne(filter, field, value, partitionKey); + } + + /// + /// For the entity selected by the filter, updates the property field with the given value. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The partition key for the document. + public virtual bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return MongoDbUpdater.UpdateOne(filter, field, value, partitionKey); + } + + /// + /// Updates the property field with the given value update a property field in entities. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The value of the partition key. + public virtual async Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return await MongoDbUpdater.UpdateOneAsync(filter, field, value, partitionKey); + } + + /// + /// For the entity selected by the filter, updates the property field with the given value. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The partition key for the document. + public virtual async Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return await MongoDbUpdater.UpdateOneAsync(Builders.Filter.Where(filter), field, value, partitionKey); + } + + #endregion Update + } + +} diff --git a/MongoDbGenericRepository/BaseReadOnlyRepository.cs b/MongoDbGenericRepository/BaseReadOnlyRepository.cs deleted file mode 100644 index 57ac920..0000000 --- a/MongoDbGenericRepository/BaseReadOnlyRepository.cs +++ /dev/null @@ -1,861 +0,0 @@ -using MongoDB.Driver; -using MongoDB.Driver.Linq; -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 -{ - 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; - - /// - /// A MongoDb Reader for read operations - /// - protected MongoDbReader MongoDbReader = 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 BaseReadOnlyRepository(string connectionString, string databaseName = null) - { - if (databaseName == null) - { - var mongoUrl = new MongoUrl(connectionString); - databaseName = databaseName ?? mongoUrl.DatabaseName; - } - ConnectionString = connectionString; - DatabaseName = databaseName; - SetupMongoDbContext(new MongoDbContext(connectionString, databaseName)); - } - - /// - /// The contructor taking a . - /// - /// A mongodb context implementing - protected BaseReadOnlyRepository(IMongoDbContext mongoDbContext) - { - SetupMongoDbContext(mongoDbContext); - } - - /// - /// The contructor taking a . - /// - /// A mongodb context implementing - protected BaseReadOnlyRepository(IMongoDatabase mongoDatabase) - { - SetupMongoDbContext(new MongoDbContext(mongoDatabase)); - } - - protected void SetupMongoDbContext(IMongoDbContext mongoDbContext) - { - MongoDbContext = mongoDbContext; - MongoDbReader = new MongoDbReader(MongoDbContext); - } - - #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. - public async virtual Task GetByIdAsync(TKey id, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return await MongoDbReader.GetByIdAsync(id, partitionKey); - } - - /// - /// 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. - public virtual TDocument GetById(TKey id, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbReader.GetById(id, partitionKey); - } - - /// - /// 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. - public async virtual Task GetOneAsync(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return await MongoDbReader.GetOneAsync(filter, partitionKey); - } - - /// - /// 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. - public virtual TDocument GetOne(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbReader.GetOne(filter, partitionKey); - } - - /// - /// 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. - public virtual IFindFluent GetCursor(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbReader.GetCursor(filter, partitionKey); - } - - /// - /// 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. - public async virtual Task AnyAsync(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return await MongoDbReader.AnyAsync(filter, partitionKey); - } - - /// - /// 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. - public virtual bool Any(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbReader.Any(filter, partitionKey); - } - - /// - /// 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. - public async virtual Task> GetAllAsync(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return await MongoDbReader.GetAllAsync(filter, partitionKey); - } - - /// - /// 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. - public virtual List GetAll(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbReader.GetAll(filter, partitionKey); - } - - /// - /// 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 - public async virtual Task CountAsync(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return await MongoDbReader.CountAsync(filter, partitionKey); - } - - /// - /// 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 - public virtual long Count(Expression> filter, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbReader.Count(filter, partitionKey); - } - - /// - /// 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. - public async virtual Task GetByMaxAsync(Expression> filter, Expression> maxValueSelector, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return await MongoDbReader.GetByMaxAsync(filter, maxValueSelector, partitionKey); - } - - /// - /// 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. - public virtual TDocument GetByMax(Expression> filter, Expression> maxValueSelector, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbReader.GetByMax(filter, maxValueSelector, partitionKey); - } - - /// - /// 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. - public async virtual Task GetByMinAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return await MongoDbReader.GetByMinAsync(filter, minValueSelector, partitionKey); - } - - /// - /// 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. - public virtual TDocument GetByMin(Expression> filter, Expression> minValueSelector, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbReader.GetByMin(filter, minValueSelector, partitionKey); - } - - /// - /// 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. - public async virtual Task GetMaxValueAsync(Expression> filter, Expression> maxValueSelector, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return await MongoDbReader.GetMaxValueAsync(filter, maxValueSelector, partitionKey); - } - - /// - /// 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. - /// The type of the value used to order the query. - /// A LINQ expression filter. - /// A property selector to order by ascending. - /// An optional partitionKey. - public virtual TValue GetMaxValue(Expression> filter, Expression> maxValueSelector, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbReader.GetMaxValue(filter, maxValueSelector, partitionKey); - } - - /// - /// 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. - public virtual async Task GetMinValueAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return await MongoDbReader.GetMinValueAsync(filter, minValueSelector, partitionKey); - } - - /// - /// 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. - public virtual TValue GetMinValue(Expression> filter, Expression> minValueSelector, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbReader.GetMinValue(filter, minValueSelector, partitionKey); - } - - #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 MongoDbReader.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 - where TKey : IEquatable - { - return MongoDbReader.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 async Task SumByAsync(Expression> filter, - Expression> selector, - string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return await MongoDbReader.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 decimal SumBy(Expression> filter, - Expression> selector, - string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbReader.SumBy(filter, selector, partitionKey); - } - - #endregion Sum TKey - - #region Utility Methods - - protected virtual 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. - /// - /// The document type. - /// The type of the primary key. - /// The document. - /// - protected virtual IMongoCollection HandlePartitioned(TDocument document) - where TDocument : IDocument - where TKey : IEquatable - { - if (document is IPartitionedDocument) - { - return GetCollection(((IPartitionedDocument)document).PartitionKey); - } - return GetCollection(); - } - - /// - /// Gets a collections for the type TDocument with a partition key. - /// - /// The document type. - /// The type of the primary key. - /// The collection partition key. - /// - protected virtual IMongoCollection GetCollection(string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return MongoDbContext.GetCollection(partitionKey); - } - - /// - /// Gets a collections for a potentially partitioned document type. - /// - /// The document type. - /// The type of the primary key. - /// The collection partition key. - /// - protected virtual IMongoCollection HandlePartitioned(string partitionKey) - where TDocument : IDocument - where TKey : IEquatable - { - if (!string.IsNullOrEmpty(partitionKey)) - { - return GetCollection(partitionKey); - } - 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 virtual 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); - } - - /// - /// Maps a IndexCreationOptions object to a MongoDB.Driver.CreateIndexOptions object - /// - /// The options for creating an index. - /// - 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, - BucketSize = indexCreationOptions.BucketSize, - Bits = indexCreationOptions.Bits, - Background = indexCreationOptions.Background, - Version = indexCreationOptions.Version - }; - } - - - /// - /// 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. - protected virtual IFindFluent GetMinMongoQuery(Expression> filter, Expression> minValueSelector, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - 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. - protected virtual IFindFluent GetMaxMongoQuery(Expression> filter, Expression> maxValueSelector, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return GetCollection(partitionKey).Find(Builders.Filter.Where(filter)) - .SortByDescending(ConvertExpression(maxValueSelector)) - .Limit(1); - } - - - #endregion - } -} diff --git a/MongoDbGenericRepository/DataAccess/Base/DataAccessBase.cs b/MongoDbGenericRepository/DataAccess/Base/DataAccessBase.cs index d6de4c6..f7a4949 100644 --- a/MongoDbGenericRepository/DataAccess/Base/DataAccessBase.cs +++ b/MongoDbGenericRepository/DataAccess/Base/DataAccessBase.cs @@ -18,7 +18,7 @@ namespace MongoDbGenericRepository.DataAccess.Base #region Utility Methods - protected virtual IMongoQueryable GetQuery(Expression> filter, string partitionKey = null) + public virtual IMongoQueryable GetQuery(Expression> filter, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { @@ -32,7 +32,7 @@ namespace MongoDbGenericRepository.DataAccess.Base /// The type of the primary key. /// The document. /// - protected virtual IMongoCollection HandlePartitioned(TDocument document) + public virtual IMongoCollection HandlePartitioned(TDocument document) where TDocument : IDocument where TKey : IEquatable { @@ -50,7 +50,7 @@ namespace MongoDbGenericRepository.DataAccess.Base /// The type of the primary key. /// The collection partition key. /// - protected virtual IMongoCollection GetCollection(string partitionKey = null) + public virtual IMongoCollection GetCollection(string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { @@ -64,7 +64,7 @@ namespace MongoDbGenericRepository.DataAccess.Base /// The type of the primary key. /// The collection partition key. /// - protected virtual IMongoCollection HandlePartitioned(string partitionKey) + public virtual IMongoCollection HandlePartitioned(string partitionKey) where TDocument : IDocument where TKey : IEquatable { diff --git a/MongoDbGenericRepository/BaseMongoDbIndexRepository.cs b/MongoDbGenericRepository/DataAccess/Index/MongoDbIndexHandler.cs similarity index 73% rename from MongoDbGenericRepository/BaseMongoDbIndexRepository.cs rename to MongoDbGenericRepository/DataAccess/Index/MongoDbIndexHandler.cs index 8edd0a7..6662670 100644 --- a/MongoDbGenericRepository/BaseMongoDbIndexRepository.cs +++ b/MongoDbGenericRepository/DataAccess/Index/MongoDbIndexHandler.cs @@ -1,4 +1,6 @@ using MongoDB.Driver; +using MongoDB.Driver.Linq; +using MongoDbGenericRepository.DataAccess.Base; using MongoDbGenericRepository.Models; using System; using System.Collections.Generic; @@ -6,10 +8,30 @@ using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; -namespace MongoDbGenericRepository +namespace MongoDbGenericRepository.DataAccess.Index { - public interface IBaseMongoDbIndexRepository + public class MongoDbIndexHandler : DataAccessBase { + public MongoDbIndexHandler(IMongoDbContext mongoDbContext) : base(mongoDbContext) + { + } + + /// + /// Returns the names of the indexes present on a collection. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// An optional partition key + /// A list containing the names of the indexes on on the concerned collection. + public async virtual Task> GetIndexesNamesAsync(string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + var indexCursor = await HandlePartitioned(partitionKey).Indexes.ListAsync(); + var indexes = await indexCursor.ToListAsync(); + return indexes.Select(e => e["name"].ToString()).ToList(); + } + /// /// Create a text index on the given field. /// IndexCreationOptions can be supplied to further specify @@ -21,133 +43,6 @@ namespace MongoDbGenericRepository /// Options for creating an index. /// An optional partition key. /// The result of the create index operation. - Task CreateTextIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Creates an index on the given field in ascending order. - /// IndexCreationOptions can be supplied to further specify - /// how the creation should be done. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The field we want to index. - /// Options for creating an index. - /// An optional partition key. - /// The result of the create index operation. - Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Creates an index on the given field in descending order. - /// IndexCreationOptions can be supplied to further specify - /// how the creation should be done. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The field we want to index. - /// Options for creating an index. - /// An optional partition key. - /// The result of the create index operation. - Task CreateDescendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Creates a hashed index on the given field. - /// IndexCreationOptions can be supplied to further specify - /// how the creation should be done. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The field we want to index. - /// Options for creating an index. - /// An optional partition key. - /// The result of the create index operation. - Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Creates a combined text index. - /// IndexCreationOptions can be supplied to further specify - /// how the creation should be done. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The fields we want to index. - /// Options for creating an index. - /// An optional partition key. - /// The result of the create index operation. - Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Drops the index given a field name - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// The name of the index - /// An optional partition key - Task DropIndexAsync(string indexName, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - - /// - /// Returns the names of the indexes present on a collection. - /// - /// The type representing a Document. - /// The type of the primary key for a Document. - /// An optional partition key - /// A list containing the names of the indexes on on the concerned collection. - Task> GetIndexesNamesAsync(string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable; - } - - public class BaseMongoDbIndexRepository : BaseReadOnlyRepository, IBaseMongoDbIndexRepository - { - /// - /// 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 BaseMongoDbIndexRepository(string connectionString, string databaseName = null) : base(connectionString, databaseName) - { - } - - /// - /// The contructor taking a . - /// - /// A mongodb context implementing - protected BaseMongoDbIndexRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext) - { - } - - /// - /// The contructor taking a . - /// - /// A mongodb context implementing - protected BaseMongoDbIndexRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase) - { - } - - #region Index Management TKey - - /// - public async virtual Task> GetIndexesNamesAsync(string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - var indexCursor = await HandlePartitioned(partitionKey).Indexes.ListAsync(); - var indexes = await indexCursor.ToListAsync(); - return indexes.Select(e => e["name"].ToString()).ToList(); - } - - /// public async virtual Task CreateTextIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable @@ -160,7 +55,17 @@ namespace MongoDbGenericRepository )); } - /// + /// + /// Creates an index on the given field in ascending order. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. public async virtual Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable @@ -173,7 +78,17 @@ namespace MongoDbGenericRepository new CreateIndexModel(indexKey.Ascending(field), createOptions)); } - /// + /// + /// Creates an index on the given field in descending order. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. public async virtual Task CreateDescendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable @@ -186,8 +101,17 @@ namespace MongoDbGenericRepository new CreateIndexModel(indexKey.Descending(field), createOptions)); } - - /// + /// + /// Creates a hashed index on the given field. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. public async virtual Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable @@ -200,7 +124,17 @@ namespace MongoDbGenericRepository new CreateIndexModel(indexKey.Hashed(field), createOptions)); } - /// + /// + /// Creates a combined text index. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The fields we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. public async virtual Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable @@ -216,15 +150,18 @@ namespace MongoDbGenericRepository .CreateOneAsync(new CreateIndexModel(Builders.IndexKeys.Combine(listOfDefs), createOptions)); } - /// + /// + /// Drops the index given a field name + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The name of the index + /// An optional partition key public async virtual Task DropIndexAsync(string indexName, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { await HandlePartitioned(partitionKey).Indexes.DropOneAsync(indexName); } - - #endregion Index Management TKey - } } diff --git a/MongoDbGenericRepository/DataAccess/Read/MongoDbReader.cs b/MongoDbGenericRepository/DataAccess/Read/MongoDbReader.Main.cs similarity index 87% rename from MongoDbGenericRepository/DataAccess/Read/MongoDbReader.cs rename to MongoDbGenericRepository/DataAccess/Read/MongoDbReader.Main.cs index a23340a..1282efd 100644 --- a/MongoDbGenericRepository/DataAccess/Read/MongoDbReader.cs +++ b/MongoDbGenericRepository/DataAccess/Read/MongoDbReader.Main.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; namespace MongoDbGenericRepository.DataAccess.Read { - public class MongoDbReader : DataAccessBase + public partial class MongoDbReader : DataAccessBase { public MongoDbReader(IMongoDbContext mongoDbContext) : base(mongoDbContext) { @@ -390,4 +390,59 @@ namespace MongoDbGenericRepository.DataAccess.Read #endregion Sum TKey } + + public partial class MongoDbReader + { + /// + /// 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. + /// + /// The type representing a Document. + /// The type of the grouping criteria. + /// The type of the projected group. + /// The grouping criteria. + /// The projected group result. + /// The partition key of your document, if any. + public virtual List GroupBy( + Expression> groupingCriteria, + Expression, TProjection>> groupProjection, + string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class, new() + { + return HandlePartitioned(partitionKey) + .Aggregate() + .Group(groupingCriteria, groupProjection) + .ToList(); + + } + + /// + /// 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. + /// + /// The type representing a Document. + /// The type of the grouping criteria. + /// The type of the projected group. + /// A LINQ expression filter. + /// The grouping criteria. + /// The projected group result. + /// The partition key of your document, if any. + public virtual List GroupBy( + Expression> filter, + Expression> selector, + Expression, TProjection>> projection, + string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class, new() + { + var collection = HandlePartitioned(partitionKey); + return collection.Aggregate() + .Match(Builders.Filter.Where(filter)) + .Group(selector, projection) + .ToList(); + } + } } diff --git a/MongoDbGenericRepository/DataAccess/Read/MongoDbReader.Project.cs b/MongoDbGenericRepository/DataAccess/Read/MongoDbReader.Project.cs new file mode 100644 index 0000000..3499a66 --- /dev/null +++ b/MongoDbGenericRepository/DataAccess/Read/MongoDbReader.Project.cs @@ -0,0 +1,90 @@ +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.Tasks; + +namespace MongoDbGenericRepository.DataAccess.Read +{ + public partial class MongoDbReader + { + /// + /// Asynchronously returns a projected document matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type representing the model you want to project to. + /// A LINQ expression filter. + /// The projection expression. + /// An optional partition key. + public virtual async Task ProjectOneAsync(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class + { + return await HandlePartitioned(partitionKey).Find(filter) + .Project(projection) + .FirstOrDefaultAsync(); + } + + /// + /// Returns a projected document matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type representing the model you want to project to. + /// A LINQ expression filter. + /// The projection expression. + /// An optional partition key. + public virtual TProjection ProjectOne(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class + { + return HandlePartitioned(partitionKey).Find(filter) + .Project(projection) + .FirstOrDefault(); + } + + /// + /// Asynchronously returns a list of projected documents matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type representing the model you want to project to. + /// A LINQ expression filter. + /// The projection expression. + /// An optional partition key. + public virtual async Task> ProjectManyAsync(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class + { + return await HandlePartitioned(partitionKey).Find(filter) + .Project(projection) + .ToListAsync(); + } + + /// + /// Asynchronously returns a list of projected documents matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type representing the model you want to project to. + /// The document filter. + /// The projection expression. + /// An optional partition key. + public virtual List ProjectMany(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class + { + return HandlePartitioned(partitionKey).Find(filter) + .Project(projection) + .ToList(); + } + } +} diff --git a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Create.cs b/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Create.cs new file mode 100644 index 0000000..7d3271b --- /dev/null +++ b/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Create.cs @@ -0,0 +1,114 @@ +using MongoDbGenericRepository.DataAccess.Create; +using MongoDbGenericRepository.Models; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace MongoDbGenericRepository +{ + public interface IKeyTypedBaseMongoDbRepository_Create where TKey : IEquatable + { + /// + /// Asynchronously adds a document to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The document you want to add. + Task AddOneAsync(TDocument document) where TDocument : IDocument; + + /// + /// Adds a document to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The document you want to add. + void AddOne(TDocument document) where TDocument : IDocument; + + /// + /// Asynchronously adds a list of documents to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The documents you want to add. + Task AddManyAsync(IEnumerable documents) where TDocument : IDocument; + + /// + /// Adds a list of documents to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The documents you want to add. + void AddMany(IEnumerable documents) where TDocument : IDocument; + } + + /// + /// 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 KeyTypedBaseMongoDbRepository : IKeyTypedBaseMongoDbRepository_Create where TKey : IEquatable + { + protected MongoDbCreator _mongoDbCreator; + protected MongoDbCreator MongoDbCreator + { + get + { + if(_mongoDbCreator == null) + { + lock (_initLock) + { + if(_mongoDbCreator == null) + { + _mongoDbCreator = new MongoDbCreator(MongoDbContext); + } + } + } + return _mongoDbCreator; + } + } + + /// + /// Asynchronously adds a document to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The document you want to add. + public virtual async Task AddOneAsync(TDocument document) where TDocument : IDocument + { + await MongoDbCreator.AddOneAsync(document); + } + + /// + /// Adds a document to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The document you want to add. + public virtual void AddOne(TDocument document) where TDocument : IDocument + { + MongoDbCreator.AddOne(document); + } + + /// + /// Asynchronously adds a list of documents to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The documents you want to add. + public virtual async Task AddManyAsync(IEnumerable documents) where TDocument : IDocument + { + await MongoDbCreator.AddManyAsync(documents); + } + + /// + /// Adds a list of documents to the collection. + /// Populates the Id and AddedAtUtc fields if necessary. + /// + /// The type representing a Document. + /// The documents you want to add. + public virtual void AddMany(IEnumerable documents) where TDocument : IDocument + { + MongoDbCreator.AddMany(documents); + } + } +} diff --git a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Delete.cs b/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Delete.cs new file mode 100644 index 0000000..c1d4d43 --- /dev/null +++ b/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Delete.cs @@ -0,0 +1,226 @@ +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 IKeyTypedBaseMongoDbRepository_Delete where TKey : IEquatable + { + /// + /// Deletes a document. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to delete. + /// The number of documents deleted. + long DeleteOne(TDocument document) + where TDocument : IDocument; + + /// + /// Asynchronously deletes a document matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to delete. + /// The number of documents deleted. + Task DeleteOneAsync(TDocument document) + where TDocument : IDocument; + + /// + /// Deletes a document matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + long DeleteOne(Expression> filter, string partitionKey = null) + where TDocument : IDocument; + + /// + /// Asynchronously deletes a document matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + Task DeleteOneAsync(Expression> filter, string partitionKey = null) + where TDocument : IDocument; + + /// + /// Asynchronously deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + Task DeleteManyAsync(Expression> filter, string partitionKey = null) + where TDocument : IDocument; + + /// + /// Asynchronously deletes a list of documents. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The list of documents to delete. + /// The number of documents deleted. + Task DeleteManyAsync(IEnumerable documents) + where TDocument : IDocument; + + /// + /// Deletes a list of documents. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The list of documents to delete. + /// The number of documents deleted. + long DeleteMany(IEnumerable documents) + where TDocument : IDocument; + + /// + /// Deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + long DeleteMany(Expression> filter, string partitionKey = null) + where TDocument : IDocument; + } + + public abstract partial class KeyTypedBaseMongoDbRepository: IKeyTypedBaseMongoDbRepository_Delete + where TKey : IEquatable + { + private MongoDbEraser _mongoDbEraser; + protected MongoDbEraser MongoDbEraser + { + get + { + if (_mongoDbEraser != null) { return _mongoDbEraser; } + + lock (_initLock) + { + if (_mongoDbEraser == null) + { + _mongoDbEraser = new MongoDbEraser(MongoDbContext); + } + } + return _mongoDbEraser; + } + } + + /// + /// Deletes a document. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to delete. + /// The number of documents deleted. + public virtual long DeleteOne(TDocument document) + where TDocument : IDocument + { + return MongoDbEraser.DeleteOne(document); + } + + /// + /// Asynchronously deletes a document matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The document you want to delete. + /// The number of documents deleted. + public virtual async Task DeleteOneAsync(TDocument document) + where TDocument : IDocument + { + return await MongoDbEraser.DeleteOneAsync(document); + } + + /// + /// Deletes a document matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public virtual long DeleteOne(Expression> filter, string partitionKey = null) + where TDocument : IDocument + { + return MongoDbEraser.DeleteOne(filter, partitionKey); + } + + /// + /// Asynchronously deletes a document matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public virtual async Task DeleteOneAsync(Expression> filter, string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbEraser.DeleteOneAsync(filter, partitionKey); + } + + /// + /// Asynchronously deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public virtual async Task DeleteManyAsync(Expression> filter, string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbEraser.DeleteManyAsync(filter, partitionKey); + } + + /// + /// Asynchronously deletes a list of documents. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The list of documents to delete. + /// The number of documents deleted. + public virtual async Task DeleteManyAsync(IEnumerable documents) + where TDocument : IDocument + { + return await MongoDbEraser.DeleteManyAsync(documents); + } + + /// + /// Deletes a list of documents. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The list of documents to delete. + /// The number of documents deleted. + public virtual long DeleteMany(IEnumerable documents) + where TDocument : IDocument + { + return MongoDbEraser.DeleteMany(documents); + } + + /// + /// Deletes the documents matching the condition of the LINQ expression filter. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// A LINQ expression filter. + /// An optional partition key. + /// The number of documents deleted. + public virtual long DeleteMany(Expression> filter, string partitionKey = null) + where TDocument : IDocument + { + return MongoDbEraser.DeleteMany(filter, partitionKey); + } + } +} diff --git a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Index.cs b/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Index.cs new file mode 100644 index 0000000..8dc9850 --- /dev/null +++ b/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Index.cs @@ -0,0 +1,226 @@ +using MongoDbGenericRepository.DataAccess.Index; +using MongoDbGenericRepository.Models; +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace MongoDbGenericRepository +{ + public interface IKeyTypedBaseMongoDbRepository_Index where TKey : IEquatable + { + /// + /// Returns the names of the indexes present on a collection. + /// + /// The type representing a Document. + /// An optional partition key + /// A list containing the names of the indexes on on the concerned collection. + Task> GetIndexesNamesAsync(string partitionKey = null) + where TDocument : IDocument; + + /// + /// Create a text index on the given field. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + Task CreateTextIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument; + + /// + /// Creates an index on the given field in ascending order. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument; + + /// + /// Creates an index on the given field in descending order. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + Task CreateDescendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument; + + /// + /// Creates a hashed index on the given field. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument; + + /// + /// Creates a combined text index. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The fields we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument; + + /// + /// Drops the index given a field name + /// + /// The type representing a Document. + /// The name of the index + /// An optional partition key + Task DropIndexAsync(string indexName, string partitionKey = null) + where TDocument : IDocument; + } + + /// + /// 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 KeyTypedBaseMongoDbRepository : IKeyTypedBaseMongoDbRepository_Index + where TKey : IEquatable + { + private MongoDbIndexHandler _mongoDbIndexHandler; + protected MongoDbIndexHandler MongoDbIndexHandler + { + get + { + if (_mongoDbIndexHandler != null) { return _mongoDbIndexHandler; } + + lock (_initLock) + { + if (_mongoDbIndexHandler == null) + { + _mongoDbIndexHandler = new MongoDbIndexHandler(MongoDbContext); + } + } + return _mongoDbIndexHandler; + } + } + + /// + /// Returns the names of the indexes present on a collection. + /// + /// The type representing a Document. + /// An optional partition key + /// A list containing the names of the indexes on on the concerned collection. + public async virtual Task> GetIndexesNamesAsync(string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbIndexHandler.GetIndexesNamesAsync(partitionKey); + } + + /// + /// Create a text index on the given field. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + public async virtual Task CreateTextIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbIndexHandler.CreateTextIndexAsync(field, indexCreationOptions, partitionKey); + } + + /// + /// Creates an index on the given field in ascending order. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + public async virtual Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbIndexHandler.CreateAscendingIndexAsync(field, indexCreationOptions, partitionKey); + } + + /// + /// Creates an index on the given field in descending order. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + public async virtual Task CreateDescendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbIndexHandler.CreateDescendingIndexAsync(field, indexCreationOptions, partitionKey); + } + + /// + /// Creates a hashed index on the given field. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The field we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + public async virtual Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbIndexHandler.CreateHashedIndexAsync(field, indexCreationOptions, partitionKey); + } + + /// + /// Creates a combined text index. + /// IndexCreationOptions can be supplied to further specify + /// how the creation should be done. + /// + /// The type representing a Document. + /// The fields we want to index. + /// Options for creating an index. + /// An optional partition key. + /// The result of the create index operation. + public async virtual Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + { + return await MongoDbIndexHandler.CreateCombinedTextIndexAsync(fields, indexCreationOptions, partitionKey); + } + + /// + /// Drops the index given a field name + /// + /// The type representing a Document. + /// The name of the index + /// An optional partition key + public async virtual Task DropIndexAsync(string indexName, string partitionKey = null) + where TDocument : IDocument + { + await MongoDbIndexHandler.DropIndexAsync(indexName, partitionKey); + } + } +} diff --git a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Main.cs b/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Main.cs new file mode 100644 index 0000000..265b7c7 --- /dev/null +++ b/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Main.cs @@ -0,0 +1,82 @@ +using MongoDB.Driver; +using MongoDbGenericRepository.Models; +using System; + +namespace MongoDbGenericRepository +{ + public interface IKeyTypedBaseMongoDbRepository : + IKeyTypedReadOnlyMongoRepository, + IKeyTypedBaseMongoDbRepository_Create, + IKeyTypedBaseMongoDbRepository_Delete, + IKeyTypedBaseMongoDbRepository_Index, + IKeyTypedBaseMongoDbRepository_Update + where TKey : IEquatable + { + } + + /// + /// 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 KeyTypedBaseMongoDbRepository : + KeyTypedReadOnlyMongoRepository, + IKeyTypedBaseMongoDbRepository + where TKey : IEquatable + { + protected readonly object _initLock = new object(); + + /// + /// 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 KeyTypedBaseMongoDbRepository(string connectionString, string databaseName = null) : base(connectionString, databaseName) + { + } + + /// + /// The contructor taking a . + /// + /// A mongodb context implementing + protected KeyTypedBaseMongoDbRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext) + { + } + + /// + /// The contructor taking a . + /// + /// A mongodb context implementing + protected KeyTypedBaseMongoDbRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase) + { + } + + /// + /// Gets a collections for a potentially partitioned document type. + /// + /// The document type. + /// The collection partition key. + /// + protected virtual IMongoCollection HandlePartitioned(string partitionKey) + where TDocument : IDocument + { + if (!string.IsNullOrEmpty(partitionKey)) + { + return GetCollection(partitionKey); + } + return GetCollection(); + } + + /// + /// Gets a collections for the type TDocument with a partition key. + /// + /// The document type. + /// The collection partition key. + /// + protected virtual IMongoCollection GetCollection(string partitionKey = null) + where TDocument : IDocument + { + return MongoDbContext.GetCollection(partitionKey); + } + } +} diff --git a/MongoDbGenericRepository/KeyTypedBaseMongoDbRepository.cs b/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Update.cs similarity index 60% rename from MongoDbGenericRepository/KeyTypedBaseMongoDbRepository.cs rename to MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Update.cs index 89cf73d..1be2d34 100644 --- a/MongoDbGenericRepository/KeyTypedBaseMongoDbRepository.cs +++ b/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Update.cs @@ -1,41 +1,120 @@ using MongoDB.Driver; -using MongoDbGenericRepository.DataAccess.Create; using MongoDbGenericRepository.DataAccess.Update; using MongoDbGenericRepository.Models; using System; -using System.Collections.Generic; 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 class KeyTypedBaseMongoDbRepository : KeyTypedReadOnlyMongoRepository, IKeyTypedReadOnlyMongoRepository where TKey : IEquatable + public interface IKeyTypedBaseMongoDbRepository_Update where TKey : IEquatable { - protected object _initLock; - protected MongoDbCreator _mongoDbCreator; - protected MongoDbCreator MongoDbCreator - { - get - { - if(_mongoDbCreator == null) - { - lock (_initLock) - { - if(_mongoDbCreator == null) - { - _mongoDbCreator = new MongoDbCreator(MongoDbContext); - } - } - } - return _mongoDbCreator; - } - } + /// + /// Asynchronously Updates a document. + /// + /// The type representing a Document. + /// The document with the modifications you want to persist. + Task UpdateOneAsync(TDocument modifiedDocument) where TDocument : IDocument; + /// + /// Updates a document. + /// + /// The type representing a Document. + /// The document with the modifications you want to persist. + bool UpdateOne(TDocument modifiedDocument) where TDocument : IDocument; + + /// + /// Takes a document you want to modify and applies the update you have defined in MongoDb. + /// + /// The type representing a Document. + /// The document you want to modify. + /// The update definition for the document. + Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) + where TDocument : IDocument; + + /// + /// Takes a document you want to modify and applies the update you have defined in MongoDb. + /// + /// The type representing a Document. + /// The document you want to modify. + /// The update definition for the document. + bool UpdateOne(TDocument documentToModify, UpdateDefinition update) + where TDocument : IDocument; + + /// + /// Updates the property field with the given value update a property field in entities. + /// + /// The type representing a Document. + /// The type of the field. + /// The document you want to modify. + /// The field selector. + /// The new value of the property field. + bool UpdateOne(TDocument documentToModify, Expression> field, TField value) + where TDocument : IDocument; + + /// + /// Updates the property field with the given value update a property field in entities. + /// + /// The type representing a Document. + /// The type of the field. + /// The document you want to modify. + /// The field selector. + /// The new value of the property field. + Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) + where TDocument : IDocument; + + /// + /// Updates the property field with the given value update a property field in entities. + /// + /// The type representing a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The value of the partition key. + bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument; + + /// + /// For the entity selected by the filter, updates the property field with the given value. + /// + /// The type representing a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The partition key for the document. + bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument; + + /// + /// Updates the property field with the given value update a property field in entities. + /// + /// The type representing a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The value of the partition key. + Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument; + + /// + /// For the entity selected by the filter, updates the property field with the given value. + /// + /// The type representing a Document. + /// The type of the field. + /// The document filter. + /// The field selector. + /// The new value of the property field. + /// The partition key for the document. + Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) + where TDocument : IDocument; + } + + public abstract partial class KeyTypedBaseMongoDbRepository : IKeyTypedBaseMongoDbRepository_Update + where TKey : IEquatable + { private MongoDbUpdater _mongoDbUpdater; protected MongoDbUpdater MongoDbUpdater { @@ -55,81 +134,6 @@ namespace MongoDbGenericRepository } } - /// - /// 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 KeyTypedBaseMongoDbRepository(string connectionString, string databaseName = null) : base(connectionString, databaseName) - { - } - - /// - /// The contructor taking a . - /// - /// A mongodb context implementing - protected KeyTypedBaseMongoDbRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext) - { - } - - /// - /// The contructor taking a . - /// - /// A mongodb context implementing - protected KeyTypedBaseMongoDbRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase) - { - } - - #region Create - - /// - /// Asynchronously adds a document to the collection. - /// Populates the Id and AddedAtUtc fields if necessary. - /// - /// The type representing a Document. - /// The document you want to add. - public virtual async Task AddOneAsync(TDocument document) where TDocument : IDocument - { - await MongoDbCreator.AddOneAsync(document); - } - - /// - /// Adds a document to the collection. - /// Populates the Id and AddedAtUtc fields if necessary. - /// - /// The type representing a Document. - /// The document you want to add. - public virtual void AddOne(TDocument document) where TDocument : IDocument - { - MongoDbCreator.AddOne(document); - } - - /// - /// Asynchronously adds a list of documents to the collection. - /// Populates the Id and AddedAtUtc fields if necessary. - /// - /// The type representing a Document. - /// The documents you want to add. - public virtual async Task AddManyAsync(IEnumerable documents) where TDocument : IDocument - { - await MongoDbCreator.AddManyAsync(documents); - } - - /// - /// Adds a list of documents to the collection. - /// Populates the Id and AddedAtUtc fields if necessary. - /// - /// The type representing a Document. - /// The documents you want to add. - public virtual void AddMany(IEnumerable documents) where TDocument : IDocument - { - MongoDbCreator.AddMany(documents); - } - - #endregion Create - - #region Update - /// /// Asynchronously Updates a document. /// @@ -261,8 +265,5 @@ namespace MongoDbGenericRepository { return await MongoDbUpdater.UpdateOneAsync(filter, field, value, partitionKey); } - - - #endregion Update } } diff --git a/MongoDbGenericRepository/KeyTypedReadOnlyMongoRepository.cs b/MongoDbGenericRepository/KeyTypedRepository/KeyTypedReadOnlyMongoRepository.cs similarity index 74% rename from MongoDbGenericRepository/KeyTypedReadOnlyMongoRepository.cs rename to MongoDbGenericRepository/KeyTypedRepository/KeyTypedReadOnlyMongoRepository.cs index 085c54a..44a1af4 100644 --- a/MongoDbGenericRepository/KeyTypedReadOnlyMongoRepository.cs +++ b/MongoDbGenericRepository/KeyTypedRepository/KeyTypedReadOnlyMongoRepository.cs @@ -3,6 +3,7 @@ using MongoDbGenericRepository.DataAccess.Read; using MongoDbGenericRepository.Models; using System; using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; @@ -12,7 +13,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 class KeyTypedReadOnlyMongoRepository : IKeyTypedReadOnlyMongoRepository where TKey : IEquatable + public abstract partial class KeyTypedReadOnlyMongoRepository : IKeyTypedReadOnlyMongoRepository where TKey : IEquatable { /// /// The connection string. @@ -376,5 +377,113 @@ namespace MongoDbGenericRepository } #endregion Maths + + #region Project + + /// + /// Asynchronously returns a projected document matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type representing the model you want to project to. + /// A LINQ expression filter. + /// The projection expression. + /// An optional partition key. + public virtual async Task ProjectOneAsync(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TProjection : class + { + return await MongoDbReader.ProjectOneAsync(filter, projection, partitionKey); + } + + /// + /// Returns a projected document matching the filter condition. + /// + /// The type representing a Document. + /// The type representing the model you want to project to. + /// A LINQ expression filter. + /// The projection expression. + /// An optional partition key. + public virtual TProjection ProjectOne(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TProjection : class + { + return MongoDbReader.ProjectOne(filter, projection, partitionKey); + } + + /// + /// Asynchronously returns a list of projected documents matching the filter condition. + /// + /// The type representing a Document. + /// The type representing the model you want to project to. + /// A LINQ expression filter. + /// The projection expression. + /// An optional partition key. + public virtual async Task> ProjectManyAsync(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TProjection : class + { + return await MongoDbReader.ProjectManyAsync(filter, projection, partitionKey); + } + + /// + /// Asynchronously returns a list of projected documents matching the filter condition. + /// + /// The type representing a Document. + /// The type representing the model you want to project to. + /// A LINQ expression filter. + /// The projection expression. + /// An optional partition key. + public virtual List ProjectMany(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TProjection : class + { + return MongoDbReader.ProjectMany(filter, projection, partitionKey); + } + + + #endregion Project + + /// + /// 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. + /// + /// The type representing a Document. + /// The type of the grouping criteria. + /// The type of the projected group. + /// The grouping criteria. + /// The projected group result. + /// The partition key of your document, if any. + public virtual List GroupBy( + Expression> groupingCriteria, + Expression, TProjection>> groupProjection, + string partitionKey = null) + where TDocument : IDocument + where TProjection : class, new() + { + return MongoDbReader.GroupBy(groupingCriteria, groupProjection, partitionKey); + } + + /// + /// 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. + /// + /// The type representing a Document. + /// The type of the grouping criteria. + /// The type of the projected group. + /// A LINQ expression filter. + /// The grouping criteria. + /// The projected group result. + /// The partition key of your document, if any. + public virtual List GroupBy( + Expression> filter, + Expression> groupingCriteria, + Expression, TProjection>> groupProjection, + string partitionKey = null) + where TDocument : IDocument + where TProjection : class, new() + { + return MongoDbReader.GroupBy(filter, groupingCriteria, groupProjection, partitionKey); + } } } \ No newline at end of file diff --git a/MongoDbGenericRepository/ReadOnlyMongoRepository.cs b/MongoDbGenericRepository/ReadOnlyMongoRepository.cs index 4dfaf7e..02484e2 100644 --- a/MongoDbGenericRepository/ReadOnlyMongoRepository.cs +++ b/MongoDbGenericRepository/ReadOnlyMongoRepository.cs @@ -3,6 +3,7 @@ using MongoDbGenericRepository.DataAccess.Read; using MongoDbGenericRepository.Models; using System; using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; @@ -39,7 +40,6 @@ namespace MongoDbGenericRepository { } - #region Read TKey /// @@ -389,5 +389,184 @@ namespace MongoDbGenericRepository #endregion Sum TKey + #region Project TKey + + /// + /// Asynchronously returns a projected document matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type representing the model you want to project to. + /// A LINQ expression filter. + /// The projection expression. + /// An optional partition key. + public virtual async Task ProjectOneAsync(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class + { + return await MongoDbReader.ProjectOneAsync(filter, projection, partitionKey); + } + + /// + /// Returns a projected document matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type representing the model you want to project to. + /// A LINQ expression filter. + /// The projection expression. + /// An optional partition key. + public virtual TProjection ProjectOne(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class + { + return MongoDbReader.ProjectOne(filter, projection, partitionKey); + } + + /// + /// Asynchronously returns a list of projected documents matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type representing the model you want to project to. + /// A LINQ expression filter. + /// The projection expression. + /// An optional partition key. + public virtual async Task> ProjectManyAsync(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class + { + return await MongoDbReader.ProjectManyAsync(filter, projection, partitionKey); + } + + /// + /// Asynchronously returns a list of projected documents matching the filter condition. + /// + /// The type representing a Document. + /// The type of the primary key for a Document. + /// The type representing the model you want to project to. + /// The document filter. + /// The projection expression. + /// An optional partition key. + public virtual List ProjectMany(Expression> filter, Expression> projection, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class + { + return MongoDbReader.ProjectMany(filter, projection, partitionKey); + } + + #endregion Project TKey + + #region Group By TKey + + /// + /// 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. + /// + /// The type representing a Document. + /// The type of the grouping criteria. + /// The type of the projected group. + /// A LINQ expression filter. + /// The grouping criteria. + /// The projected group result. + /// The partition key of your document, if any. + public virtual List GroupBy( + Expression> groupingCriteria, + Expression, TProjection>> groupProjection, + string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class, new() + { + return MongoDbReader.GroupBy(groupingCriteria, groupProjection, partitionKey); + } + + /// + /// 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. + /// + /// The type representing a Document. + /// The type of the grouping criteria. + /// The type of the projected group. + /// A LINQ expression filter. + /// The grouping criteria. + /// The projected group result. + /// The partition key of your document, if any. + public virtual List GroupBy( + Expression> filter, + Expression> groupingCriteria, + Expression, TProjection>> groupProjection, + string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + where TProjection : class, new() + { + return MongoDbReader.GroupBy(filter, groupingCriteria, groupProjection, partitionKey); + } + + #endregion Group By TKey + + /// + /// Gets a collections for a potentially partitioned document type. + /// + /// The document type. + /// The type of the primary key. + /// The document. + /// + public virtual IMongoCollection HandlePartitioned(TDocument document) + where TDocument : IDocument + where TKey : IEquatable + { + return MongoDbReader.HandlePartitioned(document); + } + + /// + /// Gets a collections for a potentially partitioned document type. + /// + /// The document type. + /// The type of the primary key. + /// The collection partition key. + /// + public virtual IMongoCollection HandlePartitioned(string partitionKey) + where TDocument : IDocument + where TKey : IEquatable + { + if (!string.IsNullOrEmpty(partitionKey)) + { + return GetCollection(partitionKey); + } + return GetCollection(); + } + + /// + /// Gets a collections for a potentially partitioned document type. + /// + /// The document type. + /// The type of the primary key. + /// The document. + /// + public virtual IMongoCollection HandlePartitioned(TDocument document) + where TDocument : IDocument + { + return MongoDbReader.HandlePartitioned(document); + } + + /// + /// Gets a collections for the type TDocument with a partition key. + /// + /// The document type. + /// The type of the primary key. + /// The collection partition key. + /// + public virtual IMongoCollection GetCollection(string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return MongoDbReader.GetCollection(partitionKey); + } } } \ No newline at end of file