From a7391e06f83f198eabdf2c88889d833453ae69fa Mon Sep 17 00:00:00 2001 From: Alexandre SPIESER Date: Thu, 11 Apr 2019 23:59:34 +0100 Subject: [PATCH 1/4] first step to split function into separate classes for better reuse and easier maintenance. --- .../MongoDbTKeyDocumentTestBase.cs | 1 + .../IKeyTypedReadOnlyMongoRepository.cs | 3 +- .../IMongoDbCollectionIndexRepository.cs | 99 +---- .../BaseMongoDbIndexRepository.cs | 230 ++++++++++ .../BaseMongoDbRepository.IndexManagement.cs | 106 +---- .../BaseMongoDbRepository.cs | 379 ++++++----------- ...epository.cs => BaseReadOnlyRepository.cs} | 224 +++++----- .../DataAccess/Base/DataAccessBase.cs | 158 +++++++ .../DataAccess/Create/MongoDbCreator.cs | 142 +++++++ .../DataAccess/Delete/MongoDbEraser.cs | 180 ++++++++ .../DataAccess/Read/MongoDbReader.cs | 393 ++++++++++++++++++ .../DataAccess/Update/MongoDbUpdater.cs | 190 +++++++++ .../KeyTypedBaseMongoDbRepository.cs | 239 ++++++++--- .../KeyTypedReadOnlyMongoRepository.cs | 154 ++++--- MongoDbGenericRepository/MongoDbContext.cs | 69 +-- .../ReadOnlyMongoRepository.cs | 356 ++++++++++++++++ 16 files changed, 2189 insertions(+), 734 deletions(-) create mode 100644 MongoDbGenericRepository/BaseMongoDbIndexRepository.cs rename MongoDbGenericRepository/{BaseRepository.cs => BaseReadOnlyRepository.cs} (84%) create mode 100644 MongoDbGenericRepository/DataAccess/Base/DataAccessBase.cs create mode 100644 MongoDbGenericRepository/DataAccess/Create/MongoDbCreator.cs create mode 100644 MongoDbGenericRepository/DataAccess/Delete/MongoDbEraser.cs create mode 100644 MongoDbGenericRepository/DataAccess/Read/MongoDbReader.cs create mode 100644 MongoDbGenericRepository/DataAccess/Update/MongoDbUpdater.cs diff --git a/CoreIntegrationTests/Infrastructure/MongoDbTKeyDocumentTestBase.cs b/CoreIntegrationTests/Infrastructure/MongoDbTKeyDocumentTestBase.cs index e4b0843..e048f14 100644 --- a/CoreIntegrationTests/Infrastructure/MongoDbTKeyDocumentTestBase.cs +++ b/CoreIntegrationTests/Infrastructure/MongoDbTKeyDocumentTestBase.cs @@ -1119,6 +1119,7 @@ namespace CoreIntegrationTests.Infrastructure #endregion Math #region Test Utils + [MethodImpl(MethodImplOptions.NoInlining)] private string GetCurrentMethod() { diff --git a/MongoDbGenericRepository/Abstractions/IKeyTypedReadOnlyMongoRepository.cs b/MongoDbGenericRepository/Abstractions/IKeyTypedReadOnlyMongoRepository.cs index a2b42c1..2b73f76 100644 --- a/MongoDbGenericRepository/Abstractions/IKeyTypedReadOnlyMongoRepository.cs +++ b/MongoDbGenericRepository/Abstractions/IKeyTypedReadOnlyMongoRepository.cs @@ -7,8 +7,7 @@ using MongoDbGenericRepository.Models; namespace MongoDbGenericRepository { - public interface IKeyTypedReadOnlyMongoRepository : IBaseReadOnlyRepository - where TKey : IEquatable + public interface IKeyTypedReadOnlyMongoRepository where TKey : IEquatable { #region Read diff --git a/MongoDbGenericRepository/Abstractions/IMongoDbCollectionIndexRepository.cs b/MongoDbGenericRepository/Abstractions/IMongoDbCollectionIndexRepository.cs index 01c0add..3fa09b9 100644 --- a/MongoDbGenericRepository/Abstractions/IMongoDbCollectionIndexRepository.cs +++ b/MongoDbGenericRepository/Abstractions/IMongoDbCollectionIndexRepository.cs @@ -9,7 +9,7 @@ namespace MongoDbGenericRepository /// /// The repository interface for managing indexes /// - public interface IMongoDbCollectionIndexRepository + public interface IMongoDbCollectionIndexRepository : IBaseMongoDbIndexRepository { /// /// Create a text index on the given field. @@ -24,21 +24,6 @@ namespace MongoDbGenericRepository Task CreateTextIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, 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 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 @@ -51,21 +36,6 @@ namespace MongoDbGenericRepository /// 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 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 @@ -79,21 +49,6 @@ namespace MongoDbGenericRepository Task CreateDescendingIndexAsync(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 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 @@ -107,21 +62,6 @@ namespace MongoDbGenericRepository Task CreateHashedIndexAsync(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 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 @@ -135,21 +75,6 @@ namespace MongoDbGenericRepository Task CreateCombinedTextIndexAsync(IEnumerable>> fields, 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 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 /// @@ -159,17 +84,6 @@ namespace MongoDbGenericRepository Task DropIndexAsync(string indexName, string partitionKey = null) where TDocument : IDocument; - /// - /// 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. /// @@ -178,16 +92,5 @@ namespace MongoDbGenericRepository /// A list containing the names of the indexes on on the concerned collection. Task> GetIndexesNamesAsync(string partitionKey = null) where TDocument : IDocument; - - /// - /// 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; } } diff --git a/MongoDbGenericRepository/BaseMongoDbIndexRepository.cs b/MongoDbGenericRepository/BaseMongoDbIndexRepository.cs new file mode 100644 index 0000000..8edd0a7 --- /dev/null +++ b/MongoDbGenericRepository/BaseMongoDbIndexRepository.cs @@ -0,0 +1,230 @@ +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 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 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; + + /// + /// 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 + { + return await HandlePartitioned(partitionKey).Indexes + .CreateOneAsync( + new CreateIndexModel( + Builders.IndexKeys.Text(field), + indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions) + )); + } + + /// + public async virtual Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + var collection = HandlePartitioned(partitionKey); + var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions); + var indexKey = Builders.IndexKeys; + return await collection.Indexes + .CreateOneAsync( + new CreateIndexModel(indexKey.Ascending(field), createOptions)); + } + + /// + public async virtual Task CreateDescendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + var collection = HandlePartitioned(partitionKey); + var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions); + var indexKey = Builders.IndexKeys; + return await collection.Indexes + .CreateOneAsync( + new CreateIndexModel(indexKey.Descending(field), createOptions)); + } + + + /// + public async virtual Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + var collection = HandlePartitioned(partitionKey); + var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions); + var indexKey = Builders.IndexKeys; + return await collection.Indexes + .CreateOneAsync( + new CreateIndexModel(indexKey.Hashed(field), createOptions)); + } + + /// + public async virtual Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + var collection = HandlePartitioned(partitionKey); + var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions); + var listOfDefs = new List>(); + foreach (var field in fields) + { + listOfDefs.Add(Builders.IndexKeys.Text(field)); + } + return await collection.Indexes + .CreateOneAsync(new CreateIndexModel(Builders.IndexKeys.Combine(listOfDefs), createOptions)); + } + + /// + 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/BaseMongoDbRepository.IndexManagement.cs b/MongoDbGenericRepository/BaseMongoDbRepository.IndexManagement.cs index 440e143..b82294f 100644 --- a/MongoDbGenericRepository/BaseMongoDbRepository.IndexManagement.cs +++ b/MongoDbGenericRepository/BaseMongoDbRepository.IndexManagement.cs @@ -23,38 +23,12 @@ namespace MongoDbGenericRepository return await CreateTextIndexAsync(field, indexCreationOptions, partitionKey); } - /// - public async Task CreateTextIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - return await HandlePartitioned(partitionKey).Indexes - .CreateOneAsync( - new CreateIndexModel( - Builders.IndexKeys.Text(field), - indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions) - )); - } - /// public async Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument { return await CreateAscendingIndexAsync(field, indexCreationOptions, partitionKey); } - /// - public async Task CreateAscendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - var collection = HandlePartitioned(partitionKey); - var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions); - var indexKey = Builders.IndexKeys; - return await collection.Indexes - .CreateOneAsync( - new CreateIndexModel(indexKey.Ascending(field), createOptions)); - } - /// public async Task CreateDescendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument @@ -62,18 +36,6 @@ namespace MongoDbGenericRepository return await CreateDescendingIndexAsync(field, indexCreationOptions, partitionKey); } - /// - public async Task CreateDescendingIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - var collection = HandlePartitioned(partitionKey); - var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions); - var indexKey = Builders.IndexKeys; - return await collection.Indexes - .CreateOneAsync( - new CreateIndexModel(indexKey.Descending(field), createOptions)); - } /// public async Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) @@ -82,40 +44,12 @@ namespace MongoDbGenericRepository return await CreateHashedIndexAsync(field, indexCreationOptions, partitionKey); } - /// - public async Task CreateHashedIndexAsync(Expression> field, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - var collection = HandlePartitioned(partitionKey); - var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions); - var indexKey = Builders.IndexKeys; - return await collection.Indexes - .CreateOneAsync( - new CreateIndexModel(indexKey.Hashed(field), createOptions)); - } - /// public async Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) where TDocument : IDocument { return await CreateCombinedTextIndexAsync(fields, indexCreationOptions, partitionKey); } - /// - public async Task CreateCombinedTextIndexAsync(IEnumerable>> fields, IndexCreationOptions indexCreationOptions = null, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - var collection = HandlePartitioned(partitionKey); - var createOptions = indexCreationOptions == null ? null : MapIndexOptions(indexCreationOptions); - var listOfDefs = new List>(); - foreach (var field in fields) - { - listOfDefs.Add(Builders.IndexKeys.Text(field)); - } - return await collection.Indexes - .CreateOneAsync(new CreateIndexModel(Builders.IndexKeys.Combine(listOfDefs), createOptions)); - } /// public async Task DropIndexAsync(string indexName, string partitionKey = null) @@ -124,14 +58,6 @@ namespace MongoDbGenericRepository await DropIndexAsync(indexName, partitionKey); } - /// - public async Task DropIndexAsync(string indexName, string partitionKey = null) - where TDocument : IDocument - where TKey : IEquatable - { - await HandlePartitioned(partitionKey).Indexes.DropOneAsync(indexName); - } - /// public async Task> GetIndexesNamesAsync(string partitionKey = null) where TDocument : IDocument @@ -139,38 +65,8 @@ namespace MongoDbGenericRepository return await GetIndexesNamesAsync(partitionKey); } - /// - public async 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(); - } - - #endregion Index Management - private 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 - }; - } + } } \ No newline at end of file diff --git a/MongoDbGenericRepository/BaseMongoDbRepository.cs b/MongoDbGenericRepository/BaseMongoDbRepository.cs index db9dd3d..2fd1ad2 100644 --- a/MongoDbGenericRepository/BaseMongoDbRepository.cs +++ b/MongoDbGenericRepository/BaseMongoDbRepository.cs @@ -1,11 +1,13 @@ 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.Threading.Tasks; -using System.Linq.Expressions; -using MongoDbGenericRepository.Models; using System.Linq; -using MongoDbGenericRepository.Utils; +using System.Linq.Expressions; +using System.Threading.Tasks; namespace MongoDbGenericRepository { @@ -15,6 +17,45 @@ namespace MongoDbGenericRepository /// 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. /// @@ -40,94 +81,6 @@ namespace MongoDbGenericRepository { } - #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 - { - FormatDocument(document); - await HandlePartitioned(document).InsertOneAsync(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 - { - FormatDocument(document); - HandlePartitioned(document).InsertOne(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 - { - if (!documents.Any()) - { - return; - } - foreach (var document in documents) - { - FormatDocument(document); - } - // cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5 - if (documents.Any(e => e is IPartitionedDocument)) - { - foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey)) - { - await HandlePartitioned(group.FirstOrDefault()).InsertManyAsync(group.ToList()); - } - } - else - { - await GetCollection().InsertManyAsync(documents.ToList()); - } - } - - /// - /// 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 - { - if (!documents.Any()) - { - return; - } - foreach (var document in documents) - { - FormatDocument(document); - } - // cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5 - if (documents.Any(e => e is IPartitionedDocument)) - { - foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey)) - { - HandlePartitioned(group.FirstOrDefault()).InsertMany(group.ToList()); - } - } - else - { - GetCollection().InsertMany(documents.ToList()); - } - } - - #endregion Create - #region Create TKey /// @@ -141,8 +94,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - FormatDocument(document); - await HandlePartitioned(document).InsertOneAsync(document); + await MongoDbCreator.AddOneAsync(document); } /// @@ -156,8 +108,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - FormatDocument(document); - HandlePartitioned(document).InsertOne(document); + MongoDbCreator.AddOne(document); } /// @@ -171,26 +122,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - if (!documents.Any()) - { - return; - } - foreach (var document in documents) - { - FormatDocument(document); - } - // cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5 - if (documents.Any(e => e is IPartitionedDocument)) - { - foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey)) - { - await HandlePartitioned(group.FirstOrDefault()).InsertManyAsync(group.ToList()); - } - } - else - { - await GetCollection().InsertManyAsync(documents.ToList()); - } + await MongoDbCreator.AddManyAsync(documents); } /// @@ -204,26 +136,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - if (!documents.Any()) - { - return; - } - foreach (var document in documents) - { - FormatDocument(document); - } - // cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5 - if (documents.Any(e => e is IPartitionedDocument)) - { - foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey)) - { - HandlePartitioned(group.FirstOrDefault()).InsertMany(group.ToList()); - } - } - else - { - GetCollection().InsertMany(documents.ToList()); - } + MongoDbCreator.AddMany(documents); } #endregion @@ -237,8 +150,7 @@ namespace MongoDbGenericRepository /// The document with the modifications you want to persist. public virtual async Task UpdateOneAsync(TDocument modifiedDocument) where TDocument : IDocument { - var updateRes = await HandlePartitioned(modifiedDocument).ReplaceOneAsync(x => x.Id == modifiedDocument.Id, modifiedDocument); - return updateRes.ModifiedCount == 1; + return await MongoDbUpdater.UpdateOneAsync(modifiedDocument); } /// @@ -248,8 +160,7 @@ namespace MongoDbGenericRepository /// The document with the modifications you want to persist. public virtual bool UpdateOne(TDocument modifiedDocument) where TDocument : IDocument { - var updateRes = HandlePartitioned(modifiedDocument).ReplaceOne(x => x.Id == modifiedDocument.Id, modifiedDocument); - return updateRes.ModifiedCount == 1; + return MongoDbUpdater.UpdateOne(modifiedDocument); } /// @@ -261,9 +172,20 @@ namespace MongoDbGenericRepository public virtual async Task UpdateOneAsync(TDocument documentToModify, UpdateDefinition update) where TDocument : IDocument { - var filter = Builders.Filter.Eq("Id", documentToModify.Id); - var updateRes = await HandlePartitioned(documentToModify).UpdateOneAsync(filter, update); - return updateRes.ModifiedCount == 1; + 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); } /// @@ -277,9 +199,7 @@ namespace MongoDbGenericRepository public virtual bool UpdateOne(TDocument documentToModify, Expression> field, TField value) where TDocument : IDocument { - var filter = Builders.Filter.Eq("Id", documentToModify.Id); - var updateRes = HandlePartitioned(documentToModify).UpdateOne(filter, Builders.Update.Set(field, value)); - return updateRes.ModifiedCount == 1; + return MongoDbUpdater.UpdateOne(documentToModify, field, value); } /// @@ -293,9 +213,7 @@ namespace MongoDbGenericRepository public virtual async Task UpdateOneAsync(TDocument documentToModify, Expression> field, TField value) where TDocument : IDocument { - var filter = Builders.Filter.Eq("Id", documentToModify.Id); - var updateRes = await HandlePartitioned(documentToModify).UpdateOneAsync(filter, Builders.Update.Set(field, value)); - return updateRes.ModifiedCount == 1; + return await MongoDbUpdater.UpdateOneAsync(documentToModify, field, value); } /// @@ -310,9 +228,7 @@ namespace MongoDbGenericRepository public virtual bool UpdateOne(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) where TDocument : IDocument { - var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); - var updateRes = collection.UpdateOne(filter, Builders.Update.Set(field, value)); - return updateRes.ModifiedCount == 1; + return MongoDbUpdater.UpdateOne(filter, field, value, partitionKey); } /// @@ -327,9 +243,7 @@ namespace MongoDbGenericRepository public virtual bool UpdateOne(Expression> filter, Expression> field, TField value, string partitionKey = null) where TDocument : IDocument { - var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); - var updateRes = collection.UpdateOne(Builders.Filter.Where(filter), Builders.Update.Set(field, value)); - return updateRes.ModifiedCount == 1; + return MongoDbUpdater.UpdateOne(filter, field, value, partitionKey); } /// @@ -344,9 +258,7 @@ namespace MongoDbGenericRepository public virtual async Task UpdateOneAsync(FilterDefinition filter, Expression> field, TField value, string partitionKey = null) where TDocument : IDocument { - var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); - var updateRes = await collection.UpdateOneAsync(filter, Builders.Update.Set(field, value)); - return updateRes.ModifiedCount == 1; + return await MongoDbUpdater.UpdateOneAsync(filter, field, value, partitionKey); } /// @@ -361,24 +273,9 @@ namespace MongoDbGenericRepository public virtual async Task UpdateOneAsync(Expression> filter, Expression> field, TField value, string partitionKey = null) where TDocument : IDocument { - var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); - var updateRes = await collection.UpdateOneAsync(Builders.Filter.Where(filter), Builders.Update.Set(field, value)); - return updateRes.ModifiedCount == 1; + return await MongoDbUpdater.UpdateOneAsync(filter, field, value, partitionKey); } - /// - /// 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 - { - var filter = Builders.Filter.Eq("Id", documentToModify.Id); - var updateRes = HandlePartitioned(documentToModify).UpdateOne(filter, update, new UpdateOptions { IsUpsert = true }); - return updateRes.ModifiedCount == 1; - } #endregion Update @@ -394,9 +291,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - var filter = Builders.Filter.Eq("Id", modifiedDocument.Id); - var updateRes = await HandlePartitioned(modifiedDocument).ReplaceOneAsync(filter, modifiedDocument); - return updateRes.ModifiedCount == 1; + return await MongoDbUpdater.UpdateOneAsync(modifiedDocument); } /// @@ -409,9 +304,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - var filter = Builders.Filter.Eq("Id", modifiedDocument.Id); - var updateRes = HandlePartitioned(modifiedDocument).ReplaceOne(filter, modifiedDocument); - return updateRes.ModifiedCount == 1; + return MongoDbUpdater.UpdateOne(modifiedDocument); } /// @@ -425,9 +318,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - var filter = Builders.Filter.Eq("Id", documentToModify.Id); - var updateRes = await HandlePartitioned(documentToModify).UpdateOneAsync(filter, update, new UpdateOptions { IsUpsert = true }); - return updateRes.ModifiedCount == 1; + return await MongoDbUpdater.UpdateOneAsync(documentToModify, update); } /// @@ -441,27 +332,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - var filter = Builders.Filter.Eq("Id", documentToModify.Id); - var updateRes = HandlePartitioned(documentToModify).UpdateOne(filter, update, new UpdateOptions { IsUpsert = true }); - return updateRes.ModifiedCount == 1; - } - - /// - /// 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 - { - var filter = Builders.Filter.Eq("Id", documentToModify.Id); - var updateRes = await HandlePartitioned(documentToModify).UpdateOneAsync(filter, Builders.Update.Set(field, value)); - return updateRes.ModifiedCount == 1; + return MongoDbUpdater.UpdateOne(documentToModify, update); } /// @@ -477,9 +348,57 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - var filter = Builders.Filter.Eq("Id", documentToModify.Id); - var updateRes = HandlePartitioned(documentToModify).UpdateOne(filter, Builders.Update.Set(field, value)); - return updateRes.ModifiedCount == 1; + 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); } /// @@ -496,9 +415,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); - var updateRes = await collection.UpdateOneAsync(filter, Builders.Update.Set(field, value)); - return updateRes.ModifiedCount == 1; + return await MongoDbUpdater.UpdateOneAsync(filter, field, value, partitionKey); } /// @@ -518,42 +435,6 @@ namespace MongoDbGenericRepository return await UpdateOneAsync(Builders.Filter.Where(filter), field, value, partitionKey); } - /// - /// 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 - { - var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); - var updateRes = collection.UpdateOne(filter, Builders.Update.Set(field, value)); - return updateRes.ModifiedCount == 1; - } - - /// - /// 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 UpdateOne(Builders.Filter.Where(filter), field, value, partitionKey); - } - #endregion Update #region Delete @@ -1055,9 +936,9 @@ namespace MongoDbGenericRepository /// 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, + Expression> filter, + int skipNumber = 0, + int takeNumber = 50, string partitionKey = null) where TDocument : IDocument { diff --git a/MongoDbGenericRepository/BaseRepository.cs b/MongoDbGenericRepository/BaseReadOnlyRepository.cs similarity index 84% rename from MongoDbGenericRepository/BaseRepository.cs rename to MongoDbGenericRepository/BaseReadOnlyRepository.cs index 823c1f8..57ac920 100644 --- a/MongoDbGenericRepository/BaseRepository.cs +++ b/MongoDbGenericRepository/BaseReadOnlyRepository.cs @@ -1,5 +1,6 @@ using MongoDB.Driver; using MongoDB.Driver.Linq; +using MongoDbGenericRepository.DataAccess.Read; using MongoDbGenericRepository.Models; using System; using System.Collections.Generic; @@ -323,6 +324,11 @@ namespace MongoDbGenericRepository /// protected IMongoDbContext MongoDbContext = null; + /// + /// A MongoDb Reader for read operations + /// + protected MongoDbReader MongoDbReader = null; + /// /// The constructor taking a connection string and a database name. /// @@ -337,7 +343,7 @@ namespace MongoDbGenericRepository } ConnectionString = connectionString; DatabaseName = databaseName; - MongoDbContext = new MongoDbContext(connectionString, databaseName); + SetupMongoDbContext(new MongoDbContext(connectionString, databaseName)); } /// @@ -346,7 +352,7 @@ namespace MongoDbGenericRepository /// A mongodb context implementing protected BaseReadOnlyRepository(IMongoDbContext mongoDbContext) { - MongoDbContext = mongoDbContext; + SetupMongoDbContext(mongoDbContext); } /// @@ -355,9 +361,14 @@ namespace MongoDbGenericRepository /// A mongodb context implementing protected BaseReadOnlyRepository(IMongoDatabase mongoDatabase) { - MongoDbContext = new MongoDbContext(mongoDatabase); + SetupMongoDbContext(new MongoDbContext(mongoDatabase)); } + protected void SetupMongoDbContext(IMongoDbContext mongoDbContext) + { + MongoDbContext = mongoDbContext; + MongoDbReader = new MongoDbReader(MongoDbContext); + } #region Read TKey @@ -368,12 +379,11 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// The Id of the document you want to get. /// An optional partition key. - public async Task GetByIdAsync(TKey id, string partitionKey = null) + public async virtual Task GetByIdAsync(TKey id, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - var filter = Builders.Filter.Eq("Id", id); - return await HandlePartitioned(partitionKey).Find(filter).FirstOrDefaultAsync(); + return await MongoDbReader.GetByIdAsync(id, partitionKey); } /// @@ -383,12 +393,11 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// The Id of the document you want to get. /// An optional partition key. - public TDocument GetById(TKey id, string partitionKey = null) + public virtual TDocument GetById(TKey id, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - var filter = Builders.Filter.Eq("Id", id); - return HandlePartitioned(partitionKey).Find(filter).FirstOrDefault(); + return MongoDbReader.GetById(id, partitionKey); } /// @@ -398,11 +407,11 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// A LINQ expression filter. /// An optional partition key. - public async Task GetOneAsync(Expression> filter, string partitionKey = null) + public async virtual Task GetOneAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - return await HandlePartitioned(partitionKey).Find(filter).FirstOrDefaultAsync(); + return await MongoDbReader.GetOneAsync(filter, partitionKey); } /// @@ -412,11 +421,11 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// A LINQ expression filter. /// An optional partition key. - public TDocument GetOne(Expression> filter, string partitionKey = null) + public virtual TDocument GetOne(Expression> filter, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - return HandlePartitioned(partitionKey).Find(filter).FirstOrDefault(); + return MongoDbReader.GetOne(filter, partitionKey); } /// @@ -426,11 +435,11 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// A LINQ expression filter. /// An optional partition key. - public IFindFluent GetCursor(Expression> filter, string partitionKey = null) + public virtual IFindFluent GetCursor(Expression> filter, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - return HandlePartitioned(partitionKey).Find(filter); + return MongoDbReader.GetCursor(filter, partitionKey); } /// @@ -440,12 +449,11 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// A LINQ expression filter. /// An optional partition key. - public async Task AnyAsync(Expression> filter, string partitionKey = null) + public async virtual Task AnyAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - var count = await HandlePartitioned(partitionKey).CountDocumentsAsync(filter); - return (count > 0); + return await MongoDbReader.AnyAsync(filter, partitionKey); } /// @@ -455,12 +463,11 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// A LINQ expression filter. /// An optional partition key. - public bool Any(Expression> filter, string partitionKey = null) + public virtual bool Any(Expression> filter, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - var count = HandlePartitioned(partitionKey).CountDocuments(filter); - return (count > 0); + return MongoDbReader.Any(filter, partitionKey); } /// @@ -470,11 +477,11 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// A LINQ expression filter. /// An optional partition key. - public async Task> GetAllAsync(Expression> filter, string partitionKey = null) + public async virtual Task> GetAllAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - return await HandlePartitioned(partitionKey).Find(filter).ToListAsync(); + return await MongoDbReader.GetAllAsync(filter, partitionKey); } /// @@ -484,11 +491,11 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// A LINQ expression filter. /// An optional partition key. - public List GetAll(Expression> filter, string partitionKey = null) + public virtual List GetAll(Expression> filter, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - return HandlePartitioned(partitionKey).Find(filter).ToList(); + return MongoDbReader.GetAll(filter, partitionKey); } /// @@ -498,11 +505,11 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// A LINQ expression filter. /// An optional partitionKey - public async Task CountAsync(Expression> filter, string partitionKey = null) + public async virtual Task CountAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - return await HandlePartitioned(partitionKey).CountDocumentsAsync(filter); + return await MongoDbReader.CountAsync(filter, partitionKey); } /// @@ -512,11 +519,11 @@ namespace MongoDbGenericRepository /// The type of the primary key for a Document. /// A LINQ expression filter. /// An optional partitionKey - public long Count(Expression> filter, string partitionKey = null) + public virtual long Count(Expression> filter, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - return HandlePartitioned(partitionKey).Find(filter).CountDocuments(); + return MongoDbReader.Count(filter, partitionKey); } /// @@ -527,14 +534,11 @@ namespace MongoDbGenericRepository /// A LINQ expression filter. /// A property selector to order by descending. /// An optional partitionKey. - public async Task GetByMaxAsync(Expression> filter, Expression> maxValueSelector, string partitionKey = null) + public async virtual Task GetByMaxAsync(Expression> filter, Expression> maxValueSelector, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - return await GetCollection(partitionKey).Find(Builders.Filter.Where(filter)) - .SortByDescending(maxValueSelector) - .Limit(1) - .FirstOrDefaultAsync(); + return await MongoDbReader.GetByMaxAsync(filter, maxValueSelector, partitionKey); } /// @@ -545,14 +549,11 @@ namespace MongoDbGenericRepository /// A LINQ expression filter. /// A property selector to order by descending. /// An optional partitionKey. - public TDocument GetByMax(Expression> filter, Expression> maxValueSelector, string partitionKey = null) + public virtual TDocument GetByMax(Expression> filter, Expression> maxValueSelector, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - return GetCollection(partitionKey).Find(Builders.Filter.Where(filter)) - .SortByDescending(maxValueSelector) - .Limit(1) - .FirstOrDefault(); + return MongoDbReader.GetByMax(filter, maxValueSelector, partitionKey); } /// @@ -563,14 +564,11 @@ namespace MongoDbGenericRepository /// A LINQ expression filter. /// A property selector to order by ascending. /// An optional partitionKey. - public async Task GetByMinAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null) + public async virtual Task GetByMinAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - return await GetCollection(partitionKey).Find(Builders.Filter.Where(filter)) - .SortBy(minValueSelector) - .Limit(1) - .FirstOrDefaultAsync(); + return await MongoDbReader.GetByMinAsync(filter, minValueSelector, partitionKey); } /// @@ -581,50 +579,11 @@ namespace MongoDbGenericRepository /// A LINQ expression filter. /// A property selector to order by ascending. /// An optional partitionKey. - public TDocument GetByMin(Expression> filter, Expression> minValueSelector, string partitionKey = null) + public virtual TDocument GetByMin(Expression> filter, Expression> minValueSelector, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - return GetCollection(partitionKey).Find(Builders.Filter.Where(filter)) - .SortBy(minValueSelector) - .Limit(1) - .FirstOrDefault(); - } - - /// - /// Gets the minimum value of a property in a mongodb collections that is satisfying the filter. - /// - /// The document type. - /// The type of the primary key. - /// The type of the value used to order the query. - /// A LINQ expression filter. - /// A property selector to order by ascending. - /// An optional partition key. - private IFindFluent GetMinMongoQuery(Expression> filter, Expression> minValueSelector, string partitionKey = null) - where TDocument : IDocument - 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. - private 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); + return MongoDbReader.GetByMin(filter, minValueSelector, partitionKey); } /// @@ -635,13 +594,11 @@ namespace MongoDbGenericRepository /// A LINQ expression filter. /// A property selector to order by ascending. /// An optional partitionKey. - public async Task GetMaxValueAsync(Expression> filter, Expression> maxValueSelector, string partitionKey = null) + public async virtual Task GetMaxValueAsync(Expression> filter, Expression> maxValueSelector, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - return await GetMaxMongoQuery(filter, maxValueSelector, partitionKey) - .Project(maxValueSelector) - .FirstOrDefaultAsync(); + return await MongoDbReader.GetMaxValueAsync(filter, maxValueSelector, partitionKey); } /// @@ -653,14 +610,11 @@ namespace MongoDbGenericRepository /// A LINQ expression filter. /// A property selector to order by ascending. /// An optional partitionKey. - public TValue GetMaxValue(Expression> filter, Expression> maxValueSelector, string partitionKey = null) + public virtual TValue GetMaxValue(Expression> filter, Expression> maxValueSelector, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { - - return GetMaxMongoQuery(filter, maxValueSelector, partitionKey) - .Project(maxValueSelector) - .FirstOrDefault(); + return MongoDbReader.GetMaxValue(filter, maxValueSelector, partitionKey); } /// @@ -676,7 +630,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - return await GetMinMongoQuery(filter, minValueSelector, partitionKey).Project(minValueSelector).FirstOrDefaultAsync(); + return await MongoDbReader.GetMinValueAsync(filter, minValueSelector, partitionKey); } /// @@ -692,7 +646,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - return GetMinMongoQuery(filter, minValueSelector, partitionKey).Project(minValueSelector).FirstOrDefault(); + return MongoDbReader.GetMinValue(filter, minValueSelector, partitionKey); } #endregion @@ -712,7 +666,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - return await GetQuery(filter, partitionKey).SumAsync(selector); + return await MongoDbReader.SumByAsync(filter, selector, partitionKey); } /// @@ -728,7 +682,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - return GetQuery(filter, partitionKey).Sum(selector); + return MongoDbReader.SumBy(filter, selector, partitionKey); } /// @@ -744,7 +698,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - return await GetQuery(filter, partitionKey).SumAsync(selector); + return await MongoDbReader.SumByAsync(filter, selector, partitionKey); } /// @@ -760,14 +714,14 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - return GetQuery(filter, partitionKey).Sum(selector); + return MongoDbReader.SumBy(filter, selector, partitionKey); } - #endregion Sums TKey + #endregion Sum TKey #region Utility Methods - protected IMongoQueryable GetQuery(Expression> filter, string partitionKey = null) + protected virtual IMongoQueryable GetQuery(Expression> filter, string partitionKey = null) where TDocument : IDocument where TKey : IEquatable { @@ -830,7 +784,7 @@ namespace MongoDbGenericRepository /// The document type. /// The type of the value. /// The expression to convert - protected static Expression> ConvertExpression(Expression> expression) + protected virtual Expression> ConvertExpression(Expression> expression) { var param = expression.Parameters[0]; Expression body = expression.Body; @@ -838,6 +792,70 @@ namespace MongoDbGenericRepository 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 new file mode 100644 index 0000000..d6de4c6 --- /dev/null +++ b/MongoDbGenericRepository/DataAccess/Base/DataAccessBase.cs @@ -0,0 +1,158 @@ +using MongoDB.Driver; +using MongoDB.Driver.Linq; +using MongoDbGenericRepository.Models; +using System; +using System.Linq; +using System.Linq.Expressions; + +namespace MongoDbGenericRepository.DataAccess.Base +{ + public class DataAccessBase + { + protected IMongoDbContext MongoDbContext; + + public DataAccessBase(IMongoDbContext mongoDbContext) + { + MongoDbContext = mongoDbContext; + } + + #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/Create/MongoDbCreator.cs b/MongoDbGenericRepository/DataAccess/Create/MongoDbCreator.cs new file mode 100644 index 0000000..bc490c7 --- /dev/null +++ b/MongoDbGenericRepository/DataAccess/Create/MongoDbCreator.cs @@ -0,0 +1,142 @@ +using MongoDB.Driver; +using MongoDB.Driver.Linq; +using MongoDbGenericRepository.DataAccess.Base; +using MongoDbGenericRepository.Models; +using MongoDbGenericRepository.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MongoDbGenericRepository.DataAccess.Create +{ + public class MongoDbCreator : DataAccessBase + { + public MongoDbCreator(IMongoDbContext mongoDbContext) : base(mongoDbContext) + { + } + + #region Create TKey + + /// + /// 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 + { + FormatDocument(document); + await HandlePartitioned(document).InsertOneAsync(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 + { + FormatDocument(document); + HandlePartitioned(document).InsertOne(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 + { + if (!documents.Any()) + { + return; + } + foreach (var document in documents) + { + FormatDocument(document); + } + // cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5 + if (documents.Any(e => e is IPartitionedDocument)) + { + foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey)) + { + await HandlePartitioned(group.FirstOrDefault()).InsertManyAsync(group.ToList()); + } + } + else + { + await GetCollection().InsertManyAsync(documents.ToList()); + } + } + + /// + /// 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 + { + if (!documents.Any()) + { + return; + } + foreach (var document in documents) + { + FormatDocument(document); + } + // cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5 + if (documents.Any(e => e is IPartitionedDocument)) + { + foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey)) + { + HandlePartitioned(group.FirstOrDefault()).InsertMany(group.ToList()); + } + } + else + { + GetCollection().InsertMany(documents.ToList()); + } + } + + #endregion + + /// + /// 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(); + } + } + } +} diff --git a/MongoDbGenericRepository/DataAccess/Delete/MongoDbEraser.cs b/MongoDbGenericRepository/DataAccess/Delete/MongoDbEraser.cs new file mode 100644 index 0000000..1daabac --- /dev/null +++ b/MongoDbGenericRepository/DataAccess/Delete/MongoDbEraser.cs @@ -0,0 +1,180 @@ +using MongoDB.Driver; +using MongoDB.Driver.Linq; +using MongoDbGenericRepository.DataAccess.Base; +using MongoDbGenericRepository.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace MongoDbGenericRepository.DataAccess.Delete +{ + public class MongoDbEraser : DataAccessBase + { + public MongoDbEraser(IMongoDbContext mongoDbContext) : base(mongoDbContext) + { + } + + #region Delete TKey + + /// + /// 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 + + } +} diff --git a/MongoDbGenericRepository/DataAccess/Read/MongoDbReader.cs b/MongoDbGenericRepository/DataAccess/Read/MongoDbReader.cs new file mode 100644 index 0000000..a23340a --- /dev/null +++ b/MongoDbGenericRepository/DataAccess/Read/MongoDbReader.cs @@ -0,0 +1,393 @@ +using MongoDB.Driver; +using MongoDB.Driver.Linq; +using MongoDbGenericRepository.DataAccess.Base; +using MongoDbGenericRepository.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace MongoDbGenericRepository.DataAccess.Read +{ + public class MongoDbReader : DataAccessBase + { + public MongoDbReader(IMongoDbContext mongoDbContext) : base(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 + { + var filter = Builders.Filter.Eq("Id", id); + return await HandlePartitioned(partitionKey).Find(filter).FirstOrDefaultAsync(); + } + + /// + /// 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 + { + var filter = Builders.Filter.Eq("Id", id); + return HandlePartitioned(partitionKey).Find(filter).FirstOrDefault(); + } + + /// + /// 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 HandlePartitioned(partitionKey).Find(filter).FirstOrDefaultAsync(); + } + + /// + /// 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 HandlePartitioned(partitionKey).Find(filter).FirstOrDefault(); + } + + /// + /// 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 HandlePartitioned(partitionKey).Find(filter); + } + + /// + /// 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 + { + var count = await HandlePartitioned(partitionKey).CountDocumentsAsync(filter); + return (count > 0); + } + + /// + /// 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 + { + var count = HandlePartitioned(partitionKey).CountDocuments(filter); + return (count > 0); + } + + /// + /// 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 HandlePartitioned(partitionKey).Find(filter).ToListAsync(); + } + + /// + /// 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 HandlePartitioned(partitionKey).Find(filter).ToList(); + } + + /// + /// 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 HandlePartitioned(partitionKey).CountDocumentsAsync(filter); + } + + /// + /// 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 HandlePartitioned(partitionKey).Find(filter).CountDocuments(); + } + + #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. + public async virtual Task GetByMaxAsync(Expression> filter, Expression> maxValueSelector, string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return await GetCollection(partitionKey).Find(Builders.Filter.Where(filter)) + .SortByDescending(maxValueSelector) + .Limit(1) + .FirstOrDefaultAsync(); + } + + /// + /// 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 GetCollection(partitionKey).Find(Builders.Filter.Where(filter)) + .SortByDescending(maxValueSelector) + .Limit(1) + .FirstOrDefault(); + } + + /// + /// 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 GetCollection(partitionKey).Find(Builders.Filter.Where(filter)) + .SortBy(minValueSelector) + .Limit(1) + .FirstOrDefaultAsync(); + } + + /// + /// 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 GetCollection(partitionKey).Find(Builders.Filter.Where(filter)) + .SortBy(minValueSelector) + .Limit(1) + .FirstOrDefault(); + } + + /// + /// 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 GetMaxMongoQuery(filter, maxValueSelector, partitionKey) + .Project(maxValueSelector) + .FirstOrDefaultAsync(); + } + + /// + /// 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 GetMaxMongoQuery(filter, maxValueSelector, partitionKey) + .Project(maxValueSelector) + .FirstOrDefault(); + } + + /// + /// 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 GetMinMongoQuery(filter, minValueSelector, partitionKey).Project(minValueSelector).FirstOrDefaultAsync(); + } + + /// + /// 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 GetMinMongoQuery(filter, minValueSelector, partitionKey).Project(minValueSelector).FirstOrDefault(); + } + + + #endregion Min / Max + + #region Sum TKey + + /// + /// Sums the values of a selected field for a given filtered collection of documents. + /// + /// The type representing a Document. + /// A LINQ expression filter. + /// The field you want to sum. + /// The partition key of your document, if any. + public virtual async Task SumByAsync(Expression> filter, + Expression> selector, + string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return await GetQuery(filter, partitionKey).SumAsync(selector); + } + + /// + /// Sums the values of a selected field for a given filtered collection of documents. + /// + /// The type representing a Document. + /// A LINQ expression filter. + /// The field you want to sum. + /// The partition key of your document, if any. + public virtual int SumBy(Expression> filter, + Expression> selector, + string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return GetQuery(filter, partitionKey).Sum(selector); + } + + /// + /// Sums the values of a selected field for a given filtered collection of documents. + /// + /// The type representing a Document. + /// A LINQ expression filter. + /// The field you want to sum. + /// The partition key of your document, if any. + public virtual async Task SumByAsync(Expression> filter, + Expression> selector, + string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return await GetQuery(filter, partitionKey).SumAsync(selector); + } + + /// + /// Sums the values of a selected field for a given filtered collection of documents. + /// + /// The type representing a Document. + /// A LINQ expression filter. + /// The field you want to sum. + /// The partition key of your document, if any. + public virtual decimal SumBy(Expression> filter, + Expression> selector, + string partitionKey = null) + where TDocument : IDocument + where TKey : IEquatable + { + return GetQuery(filter, partitionKey).Sum(selector); + } + + #endregion Sum TKey + } +} diff --git a/MongoDbGenericRepository/DataAccess/Update/MongoDbUpdater.cs b/MongoDbGenericRepository/DataAccess/Update/MongoDbUpdater.cs new file mode 100644 index 0000000..0657132 --- /dev/null +++ b/MongoDbGenericRepository/DataAccess/Update/MongoDbUpdater.cs @@ -0,0 +1,190 @@ +using MongoDB.Driver; +using MongoDB.Driver.Linq; +using MongoDbGenericRepository.DataAccess.Base; +using MongoDbGenericRepository.Models; +using MongoDbGenericRepository.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace MongoDbGenericRepository.DataAccess.Update +{ + public class MongoDbUpdater : DataAccessBase + { + public MongoDbUpdater(IMongoDbContext mongoDbContext) : base(mongoDbContext) + { + } + + /// + /// 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 + { + var filter = Builders.Filter.Eq("Id", modifiedDocument.Id); + var updateRes = await HandlePartitioned(modifiedDocument).ReplaceOneAsync(filter, modifiedDocument); + return updateRes.ModifiedCount == 1; + } + + /// + /// 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 + { + var filter = Builders.Filter.Eq("Id", modifiedDocument.Id); + var updateRes = HandlePartitioned(modifiedDocument).ReplaceOne(filter, modifiedDocument); + return updateRes.ModifiedCount == 1; + } + + /// + /// 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 + { + var filter = Builders.Filter.Eq("Id", documentToModify.Id); + var updateRes = await HandlePartitioned(documentToModify).UpdateOneAsync(filter, update, new UpdateOptions { IsUpsert = true }); + return updateRes.ModifiedCount == 1; + } + + /// + /// 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 + { + var filter = Builders.Filter.Eq("Id", documentToModify.Id); + var updateRes = HandlePartitioned(documentToModify).UpdateOne(filter, update, new UpdateOptions { IsUpsert = true }); + return updateRes.ModifiedCount == 1; + } + + /// + /// 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 + { + var filter = Builders.Filter.Eq("Id", documentToModify.Id); + var updateRes = await HandlePartitioned(documentToModify).UpdateOneAsync(filter, Builders.Update.Set(field, value)); + return updateRes.ModifiedCount == 1; + } + + /// + /// 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 + { + var filter = Builders.Filter.Eq("Id", documentToModify.Id); + var updateRes = HandlePartitioned(documentToModify).UpdateOne(filter, Builders.Update.Set(field, value)); + return updateRes.ModifiedCount == 1; + } + + /// + /// 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 + { + var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); + var updateRes = await collection.UpdateOneAsync(filter, Builders.Update.Set(field, value)); + return updateRes.ModifiedCount == 1; + } + + /// + /// 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); + } + + /// + /// 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 + { + var collection = string.IsNullOrEmpty(partitionKey) ? GetCollection() : GetCollection(partitionKey); + var updateRes = collection.UpdateOne(filter, Builders.Update.Set(field, value)); + return updateRes.ModifiedCount == 1; + } + + /// + /// 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 UpdateOne(Builders.Filter.Where(filter), field, value, partitionKey); + } + } +} diff --git a/MongoDbGenericRepository/KeyTypedBaseMongoDbRepository.cs b/MongoDbGenericRepository/KeyTypedBaseMongoDbRepository.cs index 88d6f25..89cf73d 100644 --- a/MongoDbGenericRepository/KeyTypedBaseMongoDbRepository.cs +++ b/MongoDbGenericRepository/KeyTypedBaseMongoDbRepository.cs @@ -1,9 +1,10 @@ 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 @@ -15,6 +16,45 @@ namespace MongoDbGenericRepository /// public abstract class KeyTypedBaseMongoDbRepository : KeyTypedReadOnlyMongoRepository, IKeyTypedReadOnlyMongoRepository 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; + } + } + + 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. /// @@ -50,8 +90,7 @@ namespace MongoDbGenericRepository /// The document you want to add. public virtual async Task AddOneAsync(TDocument document) where TDocument : IDocument { - FormatDocument(document); - await HandlePartitioned(document).InsertOneAsync(document); + await MongoDbCreator.AddOneAsync(document); } /// @@ -62,8 +101,7 @@ namespace MongoDbGenericRepository /// The document you want to add. public virtual void AddOne(TDocument document) where TDocument : IDocument { - FormatDocument(document); - HandlePartitioned(document).InsertOne(document); + MongoDbCreator.AddOne(document); } /// @@ -74,26 +112,7 @@ namespace MongoDbGenericRepository /// The documents you want to add. public virtual async Task AddManyAsync(IEnumerable documents) where TDocument : IDocument { - if (!documents.Any()) - { - return; - } - foreach (var document in documents) - { - FormatDocument(document); - } - // cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5 - if (documents.Any(e => e is IPartitionedDocument)) - { - foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey)) - { - await HandlePartitioned(group.FirstOrDefault()).InsertManyAsync(group.ToList()); - } - } - else - { - await GetCollection().InsertManyAsync(documents.ToList()); - } + await MongoDbCreator.AddManyAsync(documents); } /// @@ -104,48 +123,146 @@ namespace MongoDbGenericRepository /// The documents you want to add. public virtual void AddMany(IEnumerable documents) where TDocument : IDocument { - if (!documents.Any()) - { - return; - } - foreach (var document in documents) - { - FormatDocument(document); - } - // cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5 - if (documents.Any(e => e is IPartitionedDocument)) - { - foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey)) - { - HandlePartitioned(group.FirstOrDefault()).InsertMany(group.ToList()); - } - } - else - { - GetCollection().InsertMany(documents.ToList()); - } + MongoDbCreator.AddMany(documents); } #endregion Create + #region Update + /// - /// Sets the value of the document Id if it is not set already. + /// Asynchronously Updates a document. /// - /// The document type. - /// The document. - protected void FormatDocument(TDocument document) where TDocument : IDocument + /// The type representing a Document. + /// The document with the modifications you want to persist. + public virtual async Task UpdateOneAsync(TDocument modifiedDocument) where TDocument : IDocument { - 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(); - } + 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 } } diff --git a/MongoDbGenericRepository/KeyTypedReadOnlyMongoRepository.cs b/MongoDbGenericRepository/KeyTypedReadOnlyMongoRepository.cs index 3f3d37f..085c54a 100644 --- a/MongoDbGenericRepository/KeyTypedReadOnlyMongoRepository.cs +++ b/MongoDbGenericRepository/KeyTypedReadOnlyMongoRepository.cs @@ -1,9 +1,8 @@ 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; @@ -13,14 +12,43 @@ 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 : BaseReadOnlyRepository, IKeyTypedReadOnlyMongoRepository where TKey : IEquatable + public abstract class KeyTypedReadOnlyMongoRepository : IKeyTypedReadOnlyMongoRepository where TKey : IEquatable { + /// + /// The connection string. + /// + public string ConnectionString { get; protected set; } + + /// + /// The database name. + /// + public string DatabaseName { get; protected set; } + + /// + /// 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 KeyTypedReadOnlyMongoRepository(string connectionString, string databaseName = null) : base(connectionString, databaseName) + protected KeyTypedReadOnlyMongoRepository(string connectionString, string databaseName = null) + { + SetupMongoDbContext(connectionString, databaseName); + } + + /// + /// The contructor taking a . + /// + /// A mongodb context implementing + protected KeyTypedReadOnlyMongoRepository(IMongoDatabase mongoDatabase) : this(new MongoDbContext(mongoDatabase)) { } @@ -28,16 +56,27 @@ namespace MongoDbGenericRepository /// The contructor taking a . /// /// A mongodb context implementing - protected KeyTypedReadOnlyMongoRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext) + protected KeyTypedReadOnlyMongoRepository(IMongoDbContext mongoDbContext) { + SetupMongoDbContext(mongoDbContext); } - /// - /// The contructor taking a . - /// - /// A mongodb context implementing - protected KeyTypedReadOnlyMongoRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase) + protected void SetupMongoDbContext(IMongoDbContext mongoDbContext) { + MongoDbContext = MongoDbContext ?? mongoDbContext; + MongoDbReader = MongoDbReader ?? new MongoDbReader(MongoDbContext); + } + + protected void SetupMongoDbContext(string connectionString, string databaseName) + { + if (databaseName == null) + { + var mongoUrl = new MongoUrl(connectionString); + databaseName = databaseName ?? mongoUrl.DatabaseName; + } + ConnectionString = connectionString; + DatabaseName = databaseName; + SetupMongoDbContext(new MongoDbContext(connectionString, databaseName)); } #region Read @@ -50,7 +89,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public async Task GetByIdAsync(TKey id, string partitionKey = null) where TDocument : IDocument { - return await base.GetByIdAsync(id, partitionKey); + return await MongoDbReader.GetByIdAsync(id, partitionKey); } /// @@ -61,7 +100,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public TDocument GetById(TKey id, string partitionKey = null) where TDocument : IDocument { - return base.GetById(id, partitionKey); + return MongoDbReader.GetById(id, partitionKey); } /// @@ -72,7 +111,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public async Task GetOneAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return await base.GetOneAsync(filter, partitionKey); + return await MongoDbReader.GetOneAsync(filter, partitionKey); } /// @@ -83,7 +122,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public TDocument GetOne(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return base.GetOne(filter, partitionKey); + return MongoDbReader.GetOne(filter, partitionKey); } /// @@ -94,7 +133,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public IFindFluent GetCursor(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return base.GetCursor(filter, partitionKey); + return MongoDbReader.GetCursor(filter, partitionKey); } /// @@ -105,7 +144,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public async Task AnyAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return await base.AnyAsync(filter, partitionKey); + return await MongoDbReader.AnyAsync(filter, partitionKey); } /// @@ -116,7 +155,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public bool Any(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return base.Any(filter, partitionKey); + return MongoDbReader.Any(filter, partitionKey); } /// @@ -127,7 +166,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public async Task> GetAllAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return await base.GetAllAsync(filter, partitionKey); + return await MongoDbReader.GetAllAsync(filter, partitionKey); } /// @@ -138,7 +177,7 @@ namespace MongoDbGenericRepository /// An optional partition key. public List GetAll(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return base.GetAll(filter, partitionKey); + return MongoDbReader.GetAll(filter, partitionKey); } /// @@ -149,7 +188,7 @@ namespace MongoDbGenericRepository /// An optional partitionKey public async Task CountAsync(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return await base.CountAsync(filter, partitionKey); + return await MongoDbReader.CountAsync(filter, partitionKey); } /// @@ -160,7 +199,7 @@ namespace MongoDbGenericRepository /// An optional partitionKey public long Count(Expression> filter, string partitionKey = null) where TDocument : IDocument { - return base.Count(filter, partitionKey); + return MongoDbReader.Count(filter, partitionKey); } /// @@ -173,7 +212,7 @@ namespace MongoDbGenericRepository public async Task GetByMaxAsync(Expression> filter, Expression> maxValueSelector, string partitionKey = null) where TDocument : IDocument { - return await base.GetByMaxAsync(filter, maxValueSelector, partitionKey); + return await MongoDbReader.GetByMaxAsync(filter, maxValueSelector, partitionKey); } /// @@ -187,7 +226,7 @@ namespace MongoDbGenericRepository public TDocument GetByMax(Expression> filter, Expression> maxValueSelector, string partitionKey = null) where TDocument : IDocument { - return base.GetByMax(filter, maxValueSelector, partitionKey); + return MongoDbReader.GetByMax(filter, maxValueSelector, partitionKey); } /// @@ -200,7 +239,7 @@ namespace MongoDbGenericRepository public async Task GetByMinAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null) where TDocument : IDocument { - return await base.GetByMinAsync(filter, minValueSelector, partitionKey); + return await MongoDbReader.GetByMinAsync(filter, minValueSelector, partitionKey); } /// @@ -213,7 +252,7 @@ namespace MongoDbGenericRepository public TDocument GetByMin(Expression> filter, Expression> minValueSelector, string partitionKey = null) where TDocument : IDocument { - return base.GetByMin(filter, minValueSelector, partitionKey); + return MongoDbReader.GetByMin(filter, minValueSelector, partitionKey); } /// @@ -227,7 +266,7 @@ namespace MongoDbGenericRepository public async Task GetMaxValueAsync(Expression> filter, Expression> maxValueSelector, string partitionKey = null) where TDocument : IDocument { - return await base.GetMaxValueAsync(filter, maxValueSelector, partitionKey); + return await MongoDbReader.GetMaxValueAsync(filter, maxValueSelector, partitionKey); } /// @@ -241,7 +280,7 @@ namespace MongoDbGenericRepository public TValue GetMaxValue(Expression> filter, Expression> maxValueSelector, string partitionKey = null) where TDocument : IDocument { - return base.GetMaxValue(filter, maxValueSelector, partitionKey); + return MongoDbReader.GetMaxValue(filter, maxValueSelector, partitionKey); } /// @@ -255,7 +294,7 @@ namespace MongoDbGenericRepository public virtual async Task GetMinValueAsync(Expression> filter, Expression> minValueSelector, string partitionKey = null) where TDocument : IDocument { - return await base.GetMinValueAsync(filter, minValueSelector, partitionKey); + return await MongoDbReader.GetMinValueAsync(filter, minValueSelector, partitionKey); } /// @@ -269,7 +308,7 @@ namespace MongoDbGenericRepository public virtual TValue GetMinValue(Expression> filter, Expression> minValueSelector, string partitionKey = null) where TDocument : IDocument { - return base.GetMinValue(filter, minValueSelector, partitionKey); + return MongoDbReader.GetMinValue(filter, minValueSelector, partitionKey); } #endregion @@ -288,7 +327,7 @@ namespace MongoDbGenericRepository string partitionKey = null) where TDocument : IDocument { - return await base.SumByAsync(filter, selector, partitionKey); + return await MongoDbReader.SumByAsync(filter, selector, partitionKey); } /// @@ -303,7 +342,7 @@ namespace MongoDbGenericRepository string partitionKey = null) where TDocument : IDocument { - return await base.SumByAsync(filter, selector, partitionKey); + return await MongoDbReader.SumByAsync(filter, selector, partitionKey); } /// @@ -318,7 +357,7 @@ namespace MongoDbGenericRepository string partitionKey = null) where TDocument : IDocument { - return base.SumBy(filter, selector, partitionKey); + return MongoDbReader.SumBy(filter, selector, partitionKey); } /// @@ -333,58 +372,9 @@ namespace MongoDbGenericRepository string partitionKey = null) where TDocument : IDocument { - return base.SumBy(filter, selector, partitionKey); + return MongoDbReader.SumBy(filter, selector, partitionKey); } #endregion Maths - - #region Utility Methods - - /// - /// Gets a collections for the type TDocument with the matching partition key (if any). - /// - /// The document type. - /// An optional partition key. - /// An - protected virtual IMongoCollection GetCollection(string partitionKey = null) where TDocument : IDocument - { - return MongoDbContext.GetCollection(partitionKey); - } - - /// - /// 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 - { - if (document is IPartitionedDocument) - { - return GetCollection(((IPartitionedDocument)document).PartitionKey); - } - return GetCollection(); - } - - /// - /// 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 - { - if (!string.IsNullOrEmpty(partitionKey)) - { - return GetCollection(partitionKey); - } - return GetCollection(); - } - - #endregion } } \ No newline at end of file diff --git a/MongoDbGenericRepository/MongoDbContext.cs b/MongoDbGenericRepository/MongoDbContext.cs index c5921b9..a7a5520 100644 --- a/MongoDbGenericRepository/MongoDbContext.cs +++ b/MongoDbGenericRepository/MongoDbContext.cs @@ -21,24 +21,6 @@ namespace MongoDbGenericRepository /// public IMongoDatabase Database { get; } - /// - /// Sets the Guid representation of the MongoDB Driver. - /// - /// The new value of the GuidRepresentation - public virtual void SetGuidRepresentation(MongoDB.Bson.GuidRepresentation guidRepresentation) - { - MongoDefaults.GuidRepresentation = guidRepresentation; - } - - /// - /// Initialize the Guid representation of the MongoDB Driver. - /// Override this method to change the default GuidRepresentation. - /// - protected virtual void InitializeGuidRepresentation() - { - // by default, avoid legacy UUID representation: use Binary 0x04 subtype. - MongoDefaults.GuidRepresentation = MongoDB.Bson.GuidRepresentation.Standard; - } /// /// The constructor of the MongoDbContext, it needs an object implementing . @@ -76,24 +58,12 @@ namespace MongoDbGenericRepository Database = client.GetDatabase(databaseName); } - /// - /// Extracts the CollectionName attribute from the entity type, if any. - /// - /// The type representing a Document. - /// The name of the collection in which the TDocument is stored. - private string GetAttributeCollectionName() - { - return (typeof(TDocument).GetTypeInfo() - .GetCustomAttributes(typeof(CollectionNameAttribute)) - .FirstOrDefault() as CollectionNameAttribute)?.Name; - } - /// /// Returns a collection for a document type. Also handles document types with a partition key. /// /// The type representing a Document. /// The optional value of the partition key. - public IMongoCollection GetCollection(string partitionKey = null) + public virtual IMongoCollection GetCollection(string partitionKey = null) { return Database.GetCollection(GetCollectionName(partitionKey)); } @@ -102,18 +72,49 @@ namespace MongoDbGenericRepository /// Drops a collection, use very carefully. /// /// The type representing a Document. - public void DropCollection(string partitionKey = null) + public virtual void DropCollection(string partitionKey = null) { Database.DropCollection(GetCollectionName(partitionKey)); } + /// + /// Sets the Guid representation of the MongoDB Driver. + /// + /// The new value of the GuidRepresentation + public virtual void SetGuidRepresentation(MongoDB.Bson.GuidRepresentation guidRepresentation) + { + MongoDefaults.GuidRepresentation = guidRepresentation; + } + + /// + /// Extracts the CollectionName attribute from the entity type, if any. + /// + /// The type representing a Document. + /// The name of the collection in which the TDocument is stored. + protected virtual string GetAttributeCollectionName() + { + return (typeof(TDocument).GetTypeInfo() + .GetCustomAttributes(typeof(CollectionNameAttribute)) + .FirstOrDefault() as CollectionNameAttribute)?.Name; + } + + /// + /// Initialize the Guid representation of the MongoDB Driver. + /// Override this method to change the default GuidRepresentation. + /// + protected virtual void InitializeGuidRepresentation() + { + // by default, avoid legacy UUID representation: use Binary 0x04 subtype. + MongoDefaults.GuidRepresentation = MongoDB.Bson.GuidRepresentation.Standard; + } + /// /// Given the document type and the partition key, returns the name of the collection it belongs to. /// /// The type representing a Document. /// The value of the partition key. /// The name of the collection. - private string GetCollectionName(string partitionKey) + protected virtual string GetCollectionName(string partitionKey) { var collectionName = GetAttributeCollectionName() ?? Pluralize(); if (string.IsNullOrEmpty(partitionKey)) @@ -128,7 +129,7 @@ namespace MongoDbGenericRepository /// /// The type representing a Document. /// The pluralized document name. - private string Pluralize() + protected virtual string Pluralize() { return (typeof(TDocument).Name.Pluralize()).Camelize(); } diff --git a/MongoDbGenericRepository/ReadOnlyMongoRepository.cs b/MongoDbGenericRepository/ReadOnlyMongoRepository.cs index fe995a9..4dfaf7e 100644 --- a/MongoDbGenericRepository/ReadOnlyMongoRepository.cs +++ b/MongoDbGenericRepository/ReadOnlyMongoRepository.cs @@ -1,5 +1,10 @@ using MongoDB.Driver; +using MongoDbGenericRepository.DataAccess.Read; +using MongoDbGenericRepository.Models; using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Threading.Tasks; namespace MongoDbGenericRepository { @@ -33,5 +38,356 @@ namespace MongoDbGenericRepository protected ReadOnlyMongoRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase) { } + + + #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 + } } \ No newline at end of file From 29f01d2dab168a9233b418c9d7e0f6183407115d Mon Sep 17 00:00:00 2001 From: Alexandre SPIESER Date: Sun, 14 Apr 2019 17:58:31 +0100 Subject: [PATCH 2/4] better segregation of concern and interfaces. --- .../Abstractions/IBaseMongoRepository.cs | 633 +--------- .../Abstractions/IBaseReadOnlyRepository.cs | 410 +++++++ .../IKeyTypedReadOnlyMongoRepository.cs | 94 ++ .../IMongoDbCollectionIndexRepository.cs | 96 -- .../Abstractions/IReadOnlyMongoRepository.cs | 7 +- .../BaseMongoDbRepository.IndexManagement.cs | 72 -- .../BaseMongoDbRepository.cs | 1037 ----------------- .../BaseMongoRepository.Create.cs | 186 +++ .../BaseMongoRepository.Delete.cs | 343 ++++++ .../BaseMongoRepository.Index.cs | 319 +++++ .../BaseMongoRepository.Main.cs | 211 ++++ .../BaseMongoRepository.Update.cs | 457 ++++++++ .../BaseReadOnlyRepository.cs | 861 -------------- .../DataAccess/Base/DataAccessBase.cs | 8 +- .../Index/MongoDbIndexHandler.cs} | 213 ++-- ...MongoDbReader.cs => MongoDbReader.Main.cs} | 57 +- .../DataAccess/Read/MongoDbReader.Project.cs | 90 ++ .../KeyTypedBaseMongoDbRepository.Create.cs | 114 ++ .../KeyTypedBaseMongoDbRepository.Delete.cs | 226 ++++ .../KeyTypedBaseMongoDbRepository.Index.cs | 226 ++++ .../KeyTypedBaseMongoDbRepository.Main.cs | 82 ++ .../KeyTypedBaseMongoDbRepository.Update.cs} | 211 ++-- .../KeyTypedReadOnlyMongoRepository.cs | 111 +- .../ReadOnlyMongoRepository.cs | 181 ++- 24 files changed, 3296 insertions(+), 2949 deletions(-) create mode 100644 MongoDbGenericRepository/Abstractions/IBaseReadOnlyRepository.cs delete mode 100644 MongoDbGenericRepository/Abstractions/IMongoDbCollectionIndexRepository.cs delete mode 100644 MongoDbGenericRepository/BaseMongoDbRepository.IndexManagement.cs delete mode 100644 MongoDbGenericRepository/BaseMongoDbRepository.cs create mode 100644 MongoDbGenericRepository/BaseMongoRepository.Create.cs create mode 100644 MongoDbGenericRepository/BaseMongoRepository.Delete.cs create mode 100644 MongoDbGenericRepository/BaseMongoRepository.Index.cs create mode 100644 MongoDbGenericRepository/BaseMongoRepository.Main.cs create mode 100644 MongoDbGenericRepository/BaseMongoRepository.Update.cs delete mode 100644 MongoDbGenericRepository/BaseReadOnlyRepository.cs rename MongoDbGenericRepository/{BaseMongoDbIndexRepository.cs => DataAccess/Index/MongoDbIndexHandler.cs} (73%) rename MongoDbGenericRepository/DataAccess/Read/{MongoDbReader.cs => MongoDbReader.Main.cs} (87%) create mode 100644 MongoDbGenericRepository/DataAccess/Read/MongoDbReader.Project.cs create mode 100644 MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Create.cs create mode 100644 MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Delete.cs create mode 100644 MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Index.cs create mode 100644 MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Main.cs rename MongoDbGenericRepository/{KeyTypedBaseMongoDbRepository.cs => KeyTypedRepository/KeyTypedBaseMongoDbRepository.Update.cs} (60%) rename MongoDbGenericRepository/{ => KeyTypedRepository}/KeyTypedReadOnlyMongoRepository.cs (74%) 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 From 0626292d09d725cdc45f271eb55a88cdfb40a964 Mon Sep 17 00:00:00 2001 From: Alexandre SPIESER Date: Sun, 14 Apr 2019 18:10:45 +0100 Subject: [PATCH 3/4] fixed some tests --- .../MongoDbTKeyDocumentTestBase.cs | 61 +++++++++++-------- .../BaseMongoRepository.Index.cs | 4 +- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/CoreIntegrationTests/Infrastructure/MongoDbTKeyDocumentTestBase.cs b/CoreIntegrationTests/Infrastructure/MongoDbTKeyDocumentTestBase.cs index e048f14..a6e38d3 100644 --- a/CoreIntegrationTests/Infrastructure/MongoDbTKeyDocumentTestBase.cs +++ b/CoreIntegrationTests/Infrastructure/MongoDbTKeyDocumentTestBase.cs @@ -11,11 +11,11 @@ using Xunit; namespace CoreIntegrationTests.Infrastructure { - public abstract class MongoDbTKeyDocumentTestBase : + public abstract class MongoDbTKeyDocumentTestBase : IClassFixture> - where T: TestDoc, new() + where T : TestDoc, new() where TKey : IEquatable - + { private readonly MongoDbTestFixture _fixture; @@ -76,7 +76,7 @@ namespace CoreIntegrationTests.Infrastructure // Act SUT.AddOne(document); // Assert - long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count(e => e.Id.Equals(document.Id)) + long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count(e => e.Id.Equals(document.Id)) : SUT.Count(e => e.Id.Equals(document.Id), PartitionKey); Assert.True(1 == count, GetTestName()); } @@ -91,7 +91,7 @@ namespace CoreIntegrationTests.Infrastructure // Assert long count = string.IsNullOrEmpty(PartitionKey) ? SUT.Count(e => e.Id.Equals(document.Id)) : SUT.Count(e => e.Id.Equals(document.Id), PartitionKey); - Assert.True (1 == count, GetTestName()); + Assert.True(1 == count, GetTestName()); } [Fact] @@ -106,7 +106,7 @@ namespace CoreIntegrationTests.Infrastructure || e.Id.Equals(documents[1].Id)) : SUT.Count(e => e.Id.Equals(documents[0].Id) || e.Id.Equals(documents[1].Id), PartitionKey); - Assert.True (2 == count, GetTestName()); + Assert.True(2 == count, GetTestName()); } [Fact] @@ -147,7 +147,7 @@ namespace CoreIntegrationTests.Infrastructure || e.Id.Equals(documents[1].Id)) : SUT.Count(e => e.Id.Equals(documents[0].Id) || e.Id.Equals(documents[1].Id), PartitionKey); - Assert.True (2 == count, GetTestName()); + Assert.True(2 == count, GetTestName()); } [Fact] @@ -238,7 +238,7 @@ namespace CoreIntegrationTests.Infrastructure var cursor = SUT.GetCursor(x => x.Id.Equals(document.Id), PartitionKey); var count = cursor.CountDocuments(); // Assert - Assert.True (1 == count, GetTestName()); + Assert.True(1 == count, GetTestName()); } [Fact] @@ -493,10 +493,10 @@ namespace CoreIntegrationTests.Infrastructure Assert.True(result); var updatedDocument = SUT.GetById(document.Id, PartitionKey); Assert.True(null != updatedDocument); - Assert.True(childrenToAdd[0].Type== updatedDocument.Children[0].Type, GetTestName()); - Assert.True(childrenToAdd[0].Value== updatedDocument.Children[0].Value, GetTestName()); - Assert.True(childrenToAdd[1].Type== updatedDocument.Children[1].Type, GetTestName()); - Assert.True(childrenToAdd[1].Value== updatedDocument.Children[1].Value, GetTestName()); + Assert.True(childrenToAdd[0].Type == updatedDocument.Children[0].Type, GetTestName()); + Assert.True(childrenToAdd[0].Value == updatedDocument.Children[0].Value, GetTestName()); + Assert.True(childrenToAdd[1].Type == updatedDocument.Children[1].Type, GetTestName()); + Assert.True(childrenToAdd[1].Value == updatedDocument.Children[1].Value, GetTestName()); } #endregion Update @@ -512,7 +512,7 @@ namespace CoreIntegrationTests.Infrastructure // Act var result = SUT.DeleteOne(document); // Assert - Assert.True (1 == result); + Assert.True(1 == result); Assert.False(SUT.Any(e => e.Id.Equals(document.Id), PartitionKey), GetTestName()); } @@ -525,7 +525,7 @@ namespace CoreIntegrationTests.Infrastructure // Act var result = SUT.DeleteOne(e => e.Id.Equals(document.Id), PartitionKey); // Assert - Assert.True (1 == result); + Assert.True(1 == result); Assert.False(SUT.Any(e => e.Id.Equals(document.Id), PartitionKey), GetTestName()); } @@ -538,7 +538,7 @@ namespace CoreIntegrationTests.Infrastructure // Act var result = await SUT.DeleteOneAsync(document); // Assert - Assert.True (1 == result); + Assert.True(1 == result); Assert.False(SUT.Any(e => e.Id.Equals(document.Id), PartitionKey), GetTestName()); } @@ -551,7 +551,7 @@ namespace CoreIntegrationTests.Infrastructure // Act var result = await SUT.DeleteOneAsync(e => e.Id.Equals(document.Id), PartitionKey); // Assert - Assert.True (1 == result); + Assert.True(1 == result); Assert.False(SUT.Any(e => e.Id.Equals(document.Id), PartitionKey), GetTestName()); } @@ -768,7 +768,8 @@ namespace CoreIntegrationTests.Infrastructure var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; - documents.ForEach(e => { + documents.ForEach(e => + { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); @@ -790,7 +791,8 @@ namespace CoreIntegrationTests.Infrastructure var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; - documents.ForEach(e => { + documents.ForEach(e => + { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); @@ -812,7 +814,8 @@ namespace CoreIntegrationTests.Infrastructure var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; - documents.ForEach(e => { + documents.ForEach(e => + { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); @@ -834,7 +837,8 @@ namespace CoreIntegrationTests.Infrastructure var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; - documents.ForEach(e => { + documents.ForEach(e => + { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); @@ -856,7 +860,8 @@ namespace CoreIntegrationTests.Infrastructure var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; - documents.ForEach(e => { + documents.ForEach(e => + { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); @@ -878,7 +883,8 @@ namespace CoreIntegrationTests.Infrastructure var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; - documents.ForEach(e => { + documents.ForEach(e => + { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); @@ -900,7 +906,8 @@ namespace CoreIntegrationTests.Infrastructure var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; - documents.ForEach(e => { + documents.ForEach(e => + { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); @@ -908,7 +915,7 @@ namespace CoreIntegrationTests.Infrastructure var expectedMin = documents.OrderBy(e => e.Nested.SomeDate).First(); // Act - var result = SUT.GetMinValue< T, TKey, DateTime >(e => e.SomeContent == criteria, e => e.Nested.SomeDate, PartitionKey); + var result = SUT.GetMinValue(e => e.SomeContent == criteria, e => e.Nested.SomeDate, PartitionKey); // Assert Assert.True(result != default(DateTime)); @@ -922,7 +929,8 @@ namespace CoreIntegrationTests.Infrastructure var criteria = $"{GetTestName()}.{DocumentTypeName}.{Guid.NewGuid()}"; var documents = CreateTestDocuments(5); var i = 1; - documents.ForEach(e => { + documents.ForEach(e => + { e.Nested.SomeDate = e.Nested.SomeDate.AddDays(i++); e.SomeContent = criteria; }); @@ -930,7 +938,7 @@ namespace CoreIntegrationTests.Infrastructure var expectedMin = documents.OrderBy(e => e.Nested.SomeDate).First(); // Act - var result = await SUT.GetMinValueAsync< T, TKey, DateTime >(e => e.SomeContent == criteria, e => e.Nested.SomeDate, PartitionKey); + var result = await SUT.GetMinValueAsync(e => e.SomeContent == criteria, e => e.Nested.SomeDate, PartitionKey); // Assert Assert.True(result != default(DateTime)); @@ -1056,6 +1064,7 @@ namespace CoreIntegrationTests.Infrastructure // Act Expression> ex = x => x.SomeContent4; Expression> ex2 = x => x.SomeContent5; + var result = await SUT.CreateCombinedTextIndexAsync(new[] { ex, ex2 }, null, PartitionKey); // Assert diff --git a/MongoDbGenericRepository/BaseMongoRepository.Index.cs b/MongoDbGenericRepository/BaseMongoRepository.Index.cs index d973a16..2596224 100644 --- a/MongoDbGenericRepository/BaseMongoRepository.Index.cs +++ b/MongoDbGenericRepository/BaseMongoRepository.Index.cs @@ -305,7 +305,7 @@ namespace MongoDbGenericRepository public async Task DropIndexAsync(string indexName, string partitionKey = null) where TDocument : IDocument { - await MongoDbIndexHandler.DropIndexAsync(partitionKey); + await MongoDbIndexHandler.DropIndexAsync(indexName, partitionKey); } /// @@ -313,7 +313,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument where TKey : IEquatable { - await MongoDbIndexHandler.DropIndexAsync(partitionKey); + await MongoDbIndexHandler.DropIndexAsync(indexName, partitionKey); } } } \ No newline at end of file From 2207f2f1a142efad6576f29f68fbe85e6b68912a Mon Sep 17 00:00:00 2001 From: Alexandre SPIESER Date: Sun, 14 Apr 2019 19:31:28 +0100 Subject: [PATCH 4/4] rename after full refactor --- .../Abstractions/IBaseMongoRepository.cs | 9 ++++--- ...ry.cs => IReadOnlyMongoRepository.TKey.cs} | 2 +- .../Abstractions/IReadOnlyMongoRepository.cs | 2 +- .../BaseMongoRepository.Create.cs | 2 +- .../BaseMongoRepository.Delete.cs | 2 +- .../BaseMongoRepository.Index.cs | 2 +- .../BaseMongoRepository.Update.cs | 2 +- ....cs => BaseMongoRepository.TKey.Create.cs} | 4 ++-- ....cs => BaseMongoRepository.TKey.Delete.cs} | 4 ++-- ...x.cs => BaseMongoRepository.TKey.Index.cs} | 4 ++-- ...in.cs => BaseMongoRepository.TKey.Main.cs} | 24 +++++++++---------- ...s => BaseMongoRepository.TKey.ReadOnly.cs} | 8 +++---- ....cs => BaseMongoRepository.TKey.Update.cs} | 4 ++-- .../ReadOnlyMongoRepository.cs | 2 +- 14 files changed, 37 insertions(+), 34 deletions(-) rename MongoDbGenericRepository/Abstractions/{IKeyTypedReadOnlyMongoRepository.cs => IReadOnlyMongoRepository.TKey.cs} (99%) rename MongoDbGenericRepository/KeyTypedRepository/{KeyTypedBaseMongoDbRepository.Create.cs => BaseMongoRepository.TKey.Create.cs} (95%) rename MongoDbGenericRepository/KeyTypedRepository/{KeyTypedBaseMongoDbRepository.Delete.cs => BaseMongoRepository.TKey.Delete.cs} (98%) rename MongoDbGenericRepository/KeyTypedRepository/{KeyTypedBaseMongoDbRepository.Index.cs => BaseMongoRepository.TKey.Index.cs} (98%) rename MongoDbGenericRepository/KeyTypedRepository/{KeyTypedBaseMongoDbRepository.Main.cs => BaseMongoRepository.TKey.Main.cs} (75%) rename MongoDbGenericRepository/KeyTypedRepository/{KeyTypedReadOnlyMongoRepository.cs => BaseMongoRepository.TKey.ReadOnly.cs} (98%) rename MongoDbGenericRepository/KeyTypedRepository/{KeyTypedBaseMongoDbRepository.Update.cs => BaseMongoRepository.TKey.Update.cs} (98%) diff --git a/MongoDbGenericRepository/Abstractions/IBaseMongoRepository.cs b/MongoDbGenericRepository/Abstractions/IBaseMongoRepository.cs index 9f7b39f..adfe39e 100644 --- a/MongoDbGenericRepository/Abstractions/IBaseMongoRepository.cs +++ b/MongoDbGenericRepository/Abstractions/IBaseMongoRepository.cs @@ -11,10 +11,13 @@ namespace MongoDbGenericRepository /// /// The IBaseMongoRepository exposes the CRUD functionality of the BaseMongoRepository. /// - public interface IBaseMongoRepository : IReadOnlyMongoRepository, IBaseMongoRepository_Create, IBaseMongoRepository_Update, IBaseMongoRepository_Delete, IBaseMongoRepository_Index + public interface IBaseMongoRepository : + IReadOnlyMongoRepository, + IBaseMongoRepository_Create, + IBaseMongoRepository_Update, + IBaseMongoRepository_Delete, + IBaseMongoRepository_Index { - - /// /// Asynchronously returns a paginated list of the documents matching the filter condition. /// diff --git a/MongoDbGenericRepository/Abstractions/IKeyTypedReadOnlyMongoRepository.cs b/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.TKey.cs similarity index 99% rename from MongoDbGenericRepository/Abstractions/IKeyTypedReadOnlyMongoRepository.cs rename to MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.TKey.cs index 847a2a4..7790fc8 100644 --- a/MongoDbGenericRepository/Abstractions/IKeyTypedReadOnlyMongoRepository.cs +++ b/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.TKey.cs @@ -8,7 +8,7 @@ using MongoDbGenericRepository.Models; namespace MongoDbGenericRepository { - public interface IKeyTypedReadOnlyMongoRepository where TKey : IEquatable + public interface IReadOnlyMongoRepository where TKey : IEquatable { #region Read diff --git a/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs b/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs index 61d6a44..e36e8bd 100644 --- a/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs +++ b/MongoDbGenericRepository/Abstractions/IReadOnlyMongoRepository.cs @@ -9,7 +9,7 @@ namespace MongoDbGenericRepository /// /// The IReadOnlyMongoRepository exposes the readonly functionality of the BaseMongoRepository. /// - public interface IReadOnlyMongoRepository : IBaseReadOnlyRepository, IKeyTypedReadOnlyMongoRepository + public interface IReadOnlyMongoRepository : IBaseReadOnlyRepository, IReadOnlyMongoRepository { } diff --git a/MongoDbGenericRepository/BaseMongoRepository.Create.cs b/MongoDbGenericRepository/BaseMongoRepository.Create.cs index 5e772de..5d9db5a 100644 --- a/MongoDbGenericRepository/BaseMongoRepository.Create.cs +++ b/MongoDbGenericRepository/BaseMongoRepository.Create.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace MongoDbGenericRepository { - public interface IBaseMongoRepository_Create : IKeyTypedBaseMongoDbRepository_Create + public interface IBaseMongoRepository_Create : IBaseMongoRepository_Create { /// /// Asynchronously adds a document to the collection. diff --git a/MongoDbGenericRepository/BaseMongoRepository.Delete.cs b/MongoDbGenericRepository/BaseMongoRepository.Delete.cs index 5c74794..0c0491a 100644 --- a/MongoDbGenericRepository/BaseMongoRepository.Delete.cs +++ b/MongoDbGenericRepository/BaseMongoRepository.Delete.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MongoDbGenericRepository { - public interface IBaseMongoRepository_Delete : IKeyTypedBaseMongoDbRepository_Delete + public interface IBaseMongoRepository_Delete : IBaseMongoRepository_Delete { /// /// Deletes a document. diff --git a/MongoDbGenericRepository/BaseMongoRepository.Index.cs b/MongoDbGenericRepository/BaseMongoRepository.Index.cs index 2596224..9cdb64b 100644 --- a/MongoDbGenericRepository/BaseMongoRepository.Index.cs +++ b/MongoDbGenericRepository/BaseMongoRepository.Index.cs @@ -7,7 +7,7 @@ using MongoDbGenericRepository.Models; namespace MongoDbGenericRepository { - public interface IBaseMongoRepository_Index : IKeyTypedBaseMongoDbRepository_Index + public interface IBaseMongoRepository_Index : IBaseMongoRepository_Index { /// /// Returns the names of the indexes present on a collection. diff --git a/MongoDbGenericRepository/BaseMongoRepository.Update.cs b/MongoDbGenericRepository/BaseMongoRepository.Update.cs index beea2e1..4a89323 100644 --- a/MongoDbGenericRepository/BaseMongoRepository.Update.cs +++ b/MongoDbGenericRepository/BaseMongoRepository.Update.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MongoDbGenericRepository { - public interface IBaseMongoRepository_Update : IKeyTypedBaseMongoDbRepository_Update + public interface IBaseMongoRepository_Update : IBaseMongoRepository_Update { /// /// Asynchronously Updates a document. diff --git a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Create.cs b/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Create.cs similarity index 95% rename from MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Create.cs rename to MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Create.cs index 7d3271b..216f47f 100644 --- a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Create.cs +++ b/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Create.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace MongoDbGenericRepository { - public interface IKeyTypedBaseMongoDbRepository_Create where TKey : IEquatable + public interface IBaseMongoRepository_Create where TKey : IEquatable { /// /// Asynchronously adds a document to the collection. @@ -46,7 +46,7 @@ namespace MongoDbGenericRepository /// Its constructor must be given a connection string and a database name. /// /// - public abstract partial class KeyTypedBaseMongoDbRepository : IKeyTypedBaseMongoDbRepository_Create where TKey : IEquatable + public abstract partial class BaseMongoRepository : IBaseMongoRepository_Create where TKey : IEquatable { protected MongoDbCreator _mongoDbCreator; protected MongoDbCreator MongoDbCreator diff --git a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Delete.cs b/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Delete.cs similarity index 98% rename from MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Delete.cs rename to MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Delete.cs index c1d4d43..d6d3097 100644 --- a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Delete.cs +++ b/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Delete.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MongoDbGenericRepository { - public interface IKeyTypedBaseMongoDbRepository_Delete where TKey : IEquatable + public interface IBaseMongoRepository_Delete where TKey : IEquatable { /// /// Deletes a document. @@ -94,7 +94,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument; } - public abstract partial class KeyTypedBaseMongoDbRepository: IKeyTypedBaseMongoDbRepository_Delete + public abstract partial class BaseMongoRepository: IBaseMongoRepository_Delete where TKey : IEquatable { private MongoDbEraser _mongoDbEraser; diff --git a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Index.cs b/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Index.cs similarity index 98% rename from MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Index.cs rename to MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Index.cs index 8dc9850..1807ab2 100644 --- a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Index.cs +++ b/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Index.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MongoDbGenericRepository { - public interface IKeyTypedBaseMongoDbRepository_Index where TKey : IEquatable + public interface IBaseMongoRepository_Index where TKey : IEquatable { /// /// Returns the names of the indexes present on a collection. @@ -98,7 +98,7 @@ namespace MongoDbGenericRepository /// Its constructor must be given a connection string and a database name. /// /// - public abstract partial class KeyTypedBaseMongoDbRepository : IKeyTypedBaseMongoDbRepository_Index + public abstract partial class BaseMongoRepository : IBaseMongoRepository_Index where TKey : IEquatable { private MongoDbIndexHandler _mongoDbIndexHandler; diff --git a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Main.cs b/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Main.cs similarity index 75% rename from MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Main.cs rename to MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Main.cs index 265b7c7..ef79b46 100644 --- a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Main.cs +++ b/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Main.cs @@ -4,12 +4,12 @@ using System; namespace MongoDbGenericRepository { - public interface IKeyTypedBaseMongoDbRepository : - IKeyTypedReadOnlyMongoRepository, - IKeyTypedBaseMongoDbRepository_Create, - IKeyTypedBaseMongoDbRepository_Delete, - IKeyTypedBaseMongoDbRepository_Index, - IKeyTypedBaseMongoDbRepository_Update + public interface IBaseMongoDbRepository : + IReadOnlyMongoRepository, + IBaseMongoRepository_Create, + IBaseMongoRepository_Delete, + IBaseMongoRepository_Index, + IBaseMongoRepository_Update where TKey : IEquatable { } @@ -19,9 +19,9 @@ namespace MongoDbGenericRepository /// Its constructor must be given a connection string and a database name. /// /// - public abstract partial class KeyTypedBaseMongoDbRepository : - KeyTypedReadOnlyMongoRepository, - IKeyTypedBaseMongoDbRepository + public abstract partial class BaseMongoRepository : + ReadOnlyMongoRepository, + IBaseMongoDbRepository where TKey : IEquatable { protected readonly object _initLock = new object(); @@ -31,7 +31,7 @@ namespace MongoDbGenericRepository /// /// The connection string of the MongoDb server. /// The name of the database against which you want to perform operations. - protected KeyTypedBaseMongoDbRepository(string connectionString, string databaseName = null) : base(connectionString, databaseName) + protected BaseMongoRepository(string connectionString, string databaseName = null) : base(connectionString, databaseName) { } @@ -39,7 +39,7 @@ namespace MongoDbGenericRepository /// The contructor taking a . /// /// A mongodb context implementing - protected KeyTypedBaseMongoDbRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext) + protected BaseMongoRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext) { } @@ -47,7 +47,7 @@ namespace MongoDbGenericRepository /// The contructor taking a . /// /// A mongodb context implementing - protected KeyTypedBaseMongoDbRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase) + protected BaseMongoRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase) { } diff --git a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedReadOnlyMongoRepository.cs b/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.ReadOnly.cs similarity index 98% rename from MongoDbGenericRepository/KeyTypedRepository/KeyTypedReadOnlyMongoRepository.cs rename to MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.ReadOnly.cs index 44a1af4..a103005 100644 --- a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedReadOnlyMongoRepository.cs +++ b/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.ReadOnly.cs @@ -13,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 partial class KeyTypedReadOnlyMongoRepository : IKeyTypedReadOnlyMongoRepository where TKey : IEquatable + public abstract partial class ReadOnlyMongoRepository : IReadOnlyMongoRepository where TKey : IEquatable { /// /// The connection string. @@ -40,7 +40,7 @@ namespace MongoDbGenericRepository /// /// The connection string of the MongoDb server. /// The name of the database against which you want to perform operations. - protected KeyTypedReadOnlyMongoRepository(string connectionString, string databaseName = null) + protected ReadOnlyMongoRepository(string connectionString, string databaseName = null) { SetupMongoDbContext(connectionString, databaseName); } @@ -49,7 +49,7 @@ namespace MongoDbGenericRepository /// The contructor taking a . /// /// A mongodb context implementing - protected KeyTypedReadOnlyMongoRepository(IMongoDatabase mongoDatabase) : this(new MongoDbContext(mongoDatabase)) + protected ReadOnlyMongoRepository(IMongoDatabase mongoDatabase) : this(new MongoDbContext(mongoDatabase)) { } @@ -57,7 +57,7 @@ namespace MongoDbGenericRepository /// The contructor taking a . /// /// A mongodb context implementing - protected KeyTypedReadOnlyMongoRepository(IMongoDbContext mongoDbContext) + protected ReadOnlyMongoRepository(IMongoDbContext mongoDbContext) { SetupMongoDbContext(mongoDbContext); } diff --git a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Update.cs b/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Update.cs similarity index 98% rename from MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Update.cs rename to MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Update.cs index 1be2d34..8e22067 100644 --- a/MongoDbGenericRepository/KeyTypedRepository/KeyTypedBaseMongoDbRepository.Update.cs +++ b/MongoDbGenericRepository/KeyTypedRepository/BaseMongoRepository.TKey.Update.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace MongoDbGenericRepository { - public interface IKeyTypedBaseMongoDbRepository_Update where TKey : IEquatable + public interface IBaseMongoRepository_Update where TKey : IEquatable { /// /// Asynchronously Updates a document. @@ -112,7 +112,7 @@ namespace MongoDbGenericRepository where TDocument : IDocument; } - public abstract partial class KeyTypedBaseMongoDbRepository : IKeyTypedBaseMongoDbRepository_Update + public abstract partial class BaseMongoRepository : IBaseMongoRepository_Update where TKey : IEquatable { private MongoDbUpdater _mongoDbUpdater; diff --git a/MongoDbGenericRepository/ReadOnlyMongoRepository.cs b/MongoDbGenericRepository/ReadOnlyMongoRepository.cs index 02484e2..c8bcb99 100644 --- a/MongoDbGenericRepository/ReadOnlyMongoRepository.cs +++ b/MongoDbGenericRepository/ReadOnlyMongoRepository.cs @@ -13,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 ReadOnlyMongoRepository : KeyTypedReadOnlyMongoRepository, IReadOnlyMongoRepository + public abstract class ReadOnlyMongoRepository : ReadOnlyMongoRepository, IReadOnlyMongoRepository { /// /// The constructor taking a connection string and a database name.