using System; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Threading; using System.Threading.Tasks; using MongoDB.Bson.Serialization.Attributes; using MongoDB.Driver; using PoweredSoft.DynamicLinq.Helpers; using PoweredSoft.ObjectStorage.Core; namespace PoweredSoft.ObjectStorage.MongoDB { public class MongoObjectStorageCollection : IObjectStorageCollection { public MongoObjectStorageCollection(IMongoCollection collection) { if (collection == null) throw new ArgumentNullException("collection"); Collection = collection; } public string CollectionName => Collection.CollectionNamespace.CollectionName; public IMongoCollection Collection { get; } public async Task AddAsync(TEntity entity, CancellationToken cancellationToken = default(CancellationToken)) { await Collection.InsertOneAsync(entity, cancellationToken: cancellationToken); return entity; } public IQueryable AsQueryable() { return Collection.AsQueryable(); } protected virtual Expression> CreateEntityExpression(TEntity entity) { var objectKey = typeof(TEntity) .GetProperties(BindingFlags.Public | BindingFlags.Instance) .FirstOrDefault(t => t.GetCustomAttribute() != null); if (objectKey == null) throw new Exception("Must have a BsonIdAttribute on one of the properties."); var constant = objectKey.GetValue(entity); var expression = QueryableHelpers.CreateConditionExpression(objectKey.Name, DynamicLinq.ConditionOperators.Equal, constant, DynamicLinq.QueryConvertStrategy.LeaveAsIs); return expression; } public async Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default(CancellationToken)) { var expression = CreateEntityExpression(entity); await Collection.DeleteOneAsync(expression); } public async Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default(CancellationToken)) { var expression = CreateEntityExpression(entity); await Collection.ReplaceOneAsync(expression, entity); return entity; } } }