using MongoDB.Driver;
using MongoDbGenericRepository.Models;
using MongoDbGenericRepository.Utils;
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 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 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);
}
}
}