using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Threading.Tasks; using MongoDB.Driver; using MongoDbGenericRepository.Models; using MongoDbGenericRepository.Utils; 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 constructor taking a . /// /// A mongodb context implementing protected BaseMongoRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext) { } /// /// The constructor 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 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(); } /// /// 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) { 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); } #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 } }