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
}
}