reactredux/webapi/DataProviders/Abstractions/CollectionDataProviderBase.cs

213 lines
7.7 KiB
C#

using System.Linq.Expressions;
using Microsoft.Extensions.Logging;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
using DomainResults.Common;
using DomainObjects.Abstractions;
namespace DataProviders.Abstractions {
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class CollectionDataProviderBase<T> : DataProviderBase<CollectionDataProviderBase<T>> where T : DomainObjectDocumentBase<T> {
private protected readonly IIdGenerator _idGenerator;
private protected readonly ISessionService _sessionService;
private protected readonly IMongoCollection<T> _collection;
/// <summary>
/// Main constructor
/// </summary>
/// <param name="logger"></param>
/// <param name="client"></param>
/// <param name="idGenerator"></param>
/// <param name="dataProviderUtils"></param>
public CollectionDataProviderBase(
ILogger<CollectionDataProviderBase<T>> logger,
IMongoClient client,
IIdGenerator idGenerator,
ISessionService sessionService,
string databaseName,
string collectionName
) : base (logger, client, databaseName) {
_idGenerator = idGenerator;
_sessionService = sessionService;
_collection = _database.GetCollection<T>(collectionName);
}
#region Insert
public (Guid?, IDomainResult) Insert(T obj) =>
InsertAsync(obj).Result;
public (Guid?, IDomainResult) Insert(T obj, Guid sessionId) =>
InsertAsync(obj, sessionId).Result;
public Task<(Guid?, IDomainResult)> InsertAsync(T obj) =>
InsertAsync(obj, null);
public Task<(Guid?, IDomainResult)> InsertAsync(T obj, Guid sessionId) =>
InsertAsync(obj, sessionId);
private async Task<(Guid?, IDomainResult)> InsertAsync(T obj, Guid? sessionId) {
try {
if (sessionId != null)
await _collection.InsertOneAsync(_sessionService.GetSession(sessionId.Value), obj);
else
_collection.InsertOne(obj);
return IDomainResult.Success(obj.Id);
}
catch (Exception ex) {
_logger.LogError(ex, "Data provider error");
return IDomainResult.Failed<Guid?>();
}
}
#endregion
#region InsertMany
private protected (List<Guid>?, IDomainResult) InsertMany(List<T> objList) =>
InsertManyAsync(objList).Result;
private protected (List<Guid>?, IDomainResult) InsertMany(List<T> objList, Guid sessionId) =>
InsertManyAsync(objList, sessionId).Result;
private protected Task<(List<Guid>?, IDomainResult)> InsertManyAsync(List<T> objList) =>
InsertManyAsync(objList, null);
private protected Task<(List<Guid>?, IDomainResult)> InsertManyAsync(List<T> objList, Guid sessionId) =>
InsertManyAsync(objList, sessionId);
private async Task<(List<Guid>?, IDomainResult)> InsertManyAsync(List<T> objList, Guid? sessionId) {
try {
if (sessionId != null)
await _collection.InsertManyAsync(_sessionService.GetSession(sessionId.Value), objList);
else
_collection.InsertMany(objList);
return IDomainResult.Success(objList.Select(x => x.Id).ToList());
}
catch (Exception ex) {
_logger.LogError(ex, "Data provider error");
return IDomainResult.Failed<List<Guid>?>();
}
}
#endregion
#region Get
private protected (List<T>?, IDomainResult) GetWithPredicate(Expression<Func<T, bool>> predicate) =>
GetWithPredicate(predicate, 0, 0);
private protected (List<T>?, IDomainResult) GetWithPredicate(Expression<Func<T, bool>> predicate, int skip, int limit) {
try {
var result = _collection
.Find(predicate).Skip(skip).Limit(limit).ToList();
return result != null && result.Count > 0
? IDomainResult.Success(result)
: IDomainResult.NotFound<List<T>?>();
}
catch (Exception ex) {
_logger.LogError(ex, "Data provider error");
return IDomainResult.Failed<List<T>?>();
}
}
#endregion
#region Update
private protected (Guid?, IDomainResult) UpdateWithPredicate(T obj, Expression<Func<T, bool>> predicate) =>
UpdateWithPredicateAsync(obj, predicate).Result;
private protected (Guid?, IDomainResult) UpdateWithPredicate(T obj, Expression<Func<T, bool>> predicate, Guid sessionId) =>
UpdateWithPredicateAsync(obj, predicate, sessionId).Result;
private protected Task<(Guid?, IDomainResult)> UpdateWithPredicateAsync(T obj, Expression<Func<T, bool>> predicate) =>
UpdateWithPredicateAsync(obj, predicate, null);
private protected Task<(Guid?, IDomainResult)> UpdateWithPredicateAsync(T obj, Expression<Func<T, bool>> predicate, Guid sessionId) =>
UpdateWithPredicateAsync(obj, predicate, sessionId);
private async Task<(Guid?, IDomainResult)> UpdateWithPredicateAsync(T obj, Expression<Func<T, bool>> predicate, Guid? sessionId) {
try {
if (sessionId != null)
await _collection.ReplaceOneAsync(_sessionService.GetSession(sessionId.Value), predicate, obj);
else
await _collection.ReplaceOneAsync(predicate, obj);
return IDomainResult.Success(obj.Id);
}
catch (Exception ex) {
_logger.LogError(ex, "Data provider error");
return IDomainResult.Failed<Guid?>();
}
}
#endregion
#region Delete
private protected IDomainResult DeleteWithPredicate(Expression<Func<T, bool>> predicate) =>
DeleteWithPredicateAsync(predicate).Result;
private protected IDomainResult DeleteWithPredicate(Expression<Func<T, bool>> predicate, Guid sessionId) =>
DeleteWithPredicateAsync(predicate, sessionId).Result;
private protected Task<IDomainResult> DeleteWithPredicateAsync(Expression<Func<T, bool>> predicate) =>
DeleteWithPredicateAsync(predicate, null);
private protected Task<IDomainResult> DeleteWithPredicateAsync(Expression<Func<T, bool>> predicate, Guid sessionId) =>
DeleteWithPredicateAsync(predicate, sessionId);
private async Task<IDomainResult> DeleteWithPredicateAsync(Expression<Func<T, bool>> predicate, Guid? sessionId) {
try {
if (sessionId != null)
await _collection.DeleteOneAsync<T>(_sessionService.GetSession(sessionId.Value), predicate);
else
await _collection.DeleteOneAsync<T>(predicate);
return IDomainResult.Success();
}
catch (Exception ex) {
_logger.LogError(ex, "Data provider error");
return IDomainResult.Failed();
}
}
#endregion
#region DeleteMany
private protected IDomainResult DeleteManyWithPredicate(Expression<Func<T, bool>> predicate) =>
DeleteManyWithPredicateAsync(predicate).Result;
private protected IDomainResult DeleteManyWithPredicate(Expression<Func<T, bool>> predicate, Guid sessionId) =>
DeleteManyWithPredicateAsync(predicate, sessionId).Result;
private protected Task<IDomainResult> DeleteManyWithPredicateAsync(Expression<Func<T, bool>> predicate) =>
DeleteManyWithPredicateAsync(predicate, null);
private protected Task<IDomainResult> DeleteManyWithPredicateAsync(Expression<Func<T, bool>> predicate, Guid sessionId) =>
DeleteManyWithPredicateAsync(predicate, sessionId);
private async Task<IDomainResult> DeleteManyWithPredicateAsync(Expression<Func<T, bool>> predicate, Guid? sessionId) {
try {
if (sessionId != null)
await _collection.DeleteManyAsync(_sessionService.GetSession(sessionId.Value), predicate);
else
await _collection.DeleteManyAsync(predicate);
return IDomainResult.Success();
}
catch (Exception ex) {
_logger.LogError(ex, "Data provider error");
return IDomainResult.Failed();
}
}
#endregion
}
}