using System.Linq.Expressions;
using Microsoft.Extensions.Logging;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
using DomainResults.Common;
using DomainObjects.Abstractions;
namespace DataProviders.Abstractions {
///
///
///
///
public abstract class CollectionDataProviderBase : DataProviderBase> where T : DomainObjectDocumentBase {
private protected readonly IIdGenerator _idGenerator;
private protected readonly ISessionService _sessionService;
private protected readonly IMongoCollection _collection;
///
/// Main constructor
///
///
///
///
///
public CollectionDataProviderBase(
ILogger> logger,
IMongoClient client,
IIdGenerator idGenerator,
ISessionService sessionService,
string databaseName,
string collectionName
) : base (logger, client, databaseName) {
_idGenerator = idGenerator;
_sessionService = sessionService;
_collection = _database.GetCollection(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();
}
}
#endregion
#region InsertMany
private protected (List?, IDomainResult) InsertMany(List objList) =>
InsertManyAsync(objList).Result;
private protected (List?, IDomainResult) InsertMany(List objList, Guid sessionId) =>
InsertManyAsync(objList, sessionId).Result;
private protected Task<(List?, IDomainResult)> InsertManyAsync(List objList) =>
InsertManyAsync(objList, null);
private protected Task<(List?, IDomainResult)> InsertManyAsync(List objList, Guid sessionId) =>
InsertManyAsync(objList, sessionId);
private async Task<(List?, IDomainResult)> InsertManyAsync(List 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?>();
}
}
#endregion
#region Get
private protected (List?, IDomainResult) GetWithPredicate(Expression> predicate) =>
GetWithPredicate(predicate, 0, 0);
private protected (List?, IDomainResult) GetWithPredicate(Expression> 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?>();
}
catch (Exception ex) {
_logger.LogError(ex, "Data provider error");
return IDomainResult.Failed?>();
}
}
#endregion
#region Update
private protected (Guid?, IDomainResult) UpdateWithPredicate(T obj, Expression> predicate) =>
UpdateWithPredicateAsync(obj, predicate).Result;
private protected (Guid?, IDomainResult) UpdateWithPredicate(T obj, Expression> predicate, Guid sessionId) =>
UpdateWithPredicateAsync(obj, predicate, sessionId).Result;
private protected Task<(Guid?, IDomainResult)> UpdateWithPredicateAsync(T obj, Expression> predicate) =>
UpdateWithPredicateAsync(obj, predicate, null);
private protected Task<(Guid?, IDomainResult)> UpdateWithPredicateAsync(T obj, Expression> predicate, Guid sessionId) =>
UpdateWithPredicateAsync(obj, predicate, sessionId);
private async Task<(Guid?, IDomainResult)> UpdateWithPredicateAsync(T obj, Expression> 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();
}
}
#endregion
#region Delete
private protected IDomainResult DeleteWithPredicate(Expression> predicate) =>
DeleteWithPredicateAsync(predicate).Result;
private protected IDomainResult DeleteWithPredicate(Expression> predicate, Guid sessionId) =>
DeleteWithPredicateAsync(predicate, sessionId).Result;
private protected Task DeleteWithPredicateAsync(Expression> predicate) =>
DeleteWithPredicateAsync(predicate, null);
private protected Task DeleteWithPredicateAsync(Expression> predicate, Guid sessionId) =>
DeleteWithPredicateAsync(predicate, sessionId);
private async Task DeleteWithPredicateAsync(Expression> predicate, Guid? sessionId) {
try {
if (sessionId != null)
await _collection.DeleteOneAsync(_sessionService.GetSession(sessionId.Value), predicate);
else
await _collection.DeleteOneAsync(predicate);
return IDomainResult.Success();
}
catch (Exception ex) {
_logger.LogError(ex, "Data provider error");
return IDomainResult.Failed();
}
}
#endregion
#region DeleteMany
private protected IDomainResult DeleteManyWithPredicate(Expression> predicate) =>
DeleteManyWithPredicateAsync(predicate).Result;
private protected IDomainResult DeleteManyWithPredicate(Expression> predicate, Guid sessionId) =>
DeleteManyWithPredicateAsync(predicate, sessionId).Result;
private protected Task DeleteManyWithPredicateAsync(Expression> predicate) =>
DeleteManyWithPredicateAsync(predicate, null);
private protected Task DeleteManyWithPredicateAsync(Expression> predicate, Guid sessionId) =>
DeleteManyWithPredicateAsync(predicate, sessionId);
private async Task DeleteManyWithPredicateAsync(Expression> 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
}
}