using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using MongoDB.Bson;
using System.Linq.Expressions;
using MongoDbGenericRepository.Models;
namespace MongoDbGenericRepository
{
public abstract class BaseMongoRepository
{
public string ConnectionString { get; set; }
public string DatabaseName { get; set; }
///
/// The base constructor
///
/// 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)
{
_mongoDbContext = new MongoDbContext(connectionString, databaseName);
}
protected IMongoDbContext _mongoDbContext = null;
#region Get
///
/// A generic GetOne method
///
///
///
///
public async Task GetOne(string id) where TDocument : IDocument
{
var filter = Builders.Filter.Eq("Id", id);
return await GetOne(filter);
}
///
/// A generic GetOne method
///
///
///
///
public async Task GetOne(FilterDefinition filter) where TDocument : IDocument
{
return await GetCollection().Find(filter).FirstOrDefaultAsync();
}
///
/// A generic get many method with filter
///
///
///
public async Task> GetAll(FilterDefinition filter) where TDocument : IDocument
{
return await GetCollection().Find(filter).ToListAsync();
}
///
/// FindCursor
///
///
///
/// A cursor for the query
public IFindFluent FindCursor(FilterDefinition filter) where TDocument : IDocument
{
var collection = GetCollection();
var cursor = collection.Find(filter);
return cursor;
}
///
/// A generic get all method
///
///
///
public async Task> GetAll() where TDocument : IDocument
{
var collection = GetCollection();
return await collection.Find(new BsonDocument()).ToListAsync();
}
///
/// A generic Exists method
///
///
///
///
public async Task Exists(string id) where TDocument : IDocument
{
var collection = GetCollection();
var query = new BsonDocument("Id", id);
var cursor = collection.Find(query);
var count = await cursor.CountAsync();
return (count > 0);
}
///
/// A generic count method
///
///
///
///
public async Task Count(string id) where TDocument : IDocument
{
var filter = new FilterDefinitionBuilder().Eq("Id", id);
return await Count(filter);
}
///
/// A generic count method
///
///
///
///
public async Task Count(FilterDefinition filter) where TDocument : IDocument
{
var collection = GetCollection();
var cursor = collection.Find(filter);
var count = await cursor.CountAsync();
return count;
}
///
/// A generic count method
///
///
///
///
public async Task CountAsync(Expression> filter) where TDocument : IDocument
{
var collection = GetCollection();
var cursor = collection.Find(filter);
var count = await cursor.CountAsync();
return count;
}
///
/// A generic count method
///
///
///
///
public long Count(Expression> filter) where TDocument : IDocument
{
return GetCollection().Find(filter).Count();
}
///
/// Returns a list of projected objects
///
/// T is a DbEntity
///
///
public async Task ProjectBy(Expression> filter, Expression> projection)
where TDocument : IDocument
where TProjection : class, new()
{
return await GetCollection().Find(Builders.Filter.Where(filter))
.Project(projection)
.FirstOrDefaultAsync();
}
#endregion Get
#region Create
///
/// A generic Add One method async
///
///
///
///
public async Task AddOneAsync(TDocument item) where TDocument : IDocument
{
await GetCollection().InsertOneAsync(item);
}
///
/// A generic method to add a document
///
///
///
///
public void AddOne(TDocument item) where TDocument : IDocument
{
if (item.Id == default(Guid))
{
item.Id = Guid.NewGuid();
}
if (item.AddedAtUtc == default(DateTime))
{
item.AddedAtUtc = DateTime.UtcNow;
}
GetCollection().InsertOne(item);
}
///
/// A generic Add Many method, performs a bulk insert in mongo
///
///
///
///
public async Task AddManyAsync(IEnumerable items) where TDocument : IDocument
{
await GetCollection().InsertManyAsync(items);
}
///
/// A generic Add Many method, performs a bulk insert in mongo
///
///
///
///
public void AddMany(IEnumerable items) where TDocument : IDocument
{
GetCollection().InsertMany(items);
}
#endregion Create
#region Delete
///
/// A generic delete one method
///
///
///
///
public async Task DeleteOneAsync(TDocument document) where TDocument : IDocument
{
return await DeleteOneAsync(x => x.Id == document.Id);
}
///
/// A generic delete one method
///
///
///
///
public long DeleteOne(TDocument document) where TDocument : IDocument
{
return DeleteOne(x => x.Id == document.Id);
}
///
/// A generic delete one method
///
///
///
///
public long DeleteOne(Expression> filter) where TDocument : IDocument
{
return GetCollection().DeleteOne(filter).DeletedCount;
}
///
/// A generic delete one method
///
///
///
///
public async Task DeleteOneAsync(Expression> filter) where TDocument : IDocument
{
return (await GetCollection().DeleteOneAsync(filter)).DeletedCount;
}
///
/// A generic delete many method
///
///
///
///
public async Task DeleteMany(Expression> filter) where TDocument : IDocument
{
var deleteRes = await GetCollection().DeleteManyAsync(filter);
return deleteRes.DeletedCount;
}
#endregion Delete
#region Update
///
/// Updates a document
///
///
///
///
public async Task UpdateOneAsync(TDocument entity) where TDocument : IDocument
{
var updateRes = await GetCollection().ReplaceOneAsync(x => x.Id == entity.Id, entity);
return updateRes.ModifiedCount < 1;
}
///
/// UpdateOne with filter
///
///
///
///
///
private async Task UpdateOne(FilterDefinition filter, UpdateDefinition update) where TDocument : IDocument
{
var updateRes = await GetCollection().UpdateOneAsync(filter, update);
return updateRes.ModifiedCount;
}
///
/// UpdateMany with filter
///
///
///
///
///
public async Task UpdateMany(FilterDefinition filter, UpdateDefinition update) where TDocument : IDocument
{
var collection = GetCollection();
var updateRes = await collection.UpdateManyAsync(filter, update);
return updateRes.ModifiedCount;
}
#endregion Update
#region Find And Update
///
/// GetAndUpdateOne with filter
///
///
///
///
///
///
public async Task GetAndUpdateOne(FilterDefinition filter, UpdateDefinition update, FindOneAndUpdateOptions options) where TDocument : IDocument
{
return await GetCollection().FindOneAndUpdateAsync(filter, update, options);
}
#endregion Find And Update
///
/// The private GetCollection method
///
///
///
private IMongoCollection GetCollection(TDocument document) where TDocument : IDocument
{
return _mongoDbContext.GetCollection(document);
}
///
/// The private GetCollection method
///
///
///
private IMongoCollection GetCollection() where TDocument : IDocument
{
return _mongoDbContext.GetCollection();
}
}
}