using MongoDB.Driver; using MongoDB.Driver.Linq; using MongoDbGenericRepository.Models; using System; using System.Linq; using System.Linq.Expressions; namespace MongoDbGenericRepository.DataAccess.Base { /// /// A base class for accessing the Database and its Collections. /// public class DataAccessBase : IDataAccessBase { /// /// The MongoDbContext /// protected IMongoDbContext MongoDbContext; /// /// The constructor of the DataAccessBase class /// /// public DataAccessBase(IMongoDbContext mongoDbContext) { MongoDbContext = mongoDbContext; } #region Utility Methods /// /// Gets a IMongoQueryable for a potentially partitioned document type and a filter. /// /// The document type. /// The type of the primary key. /// The filter definition. /// The collection partition key. /// public virtual IQueryable 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. /// public 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. /// public 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. /// public 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, 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 } }