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