adding Key typed base repo functionality

This commit is contained in:
Alexandre SPIESER
2019-04-04 23:45:07 +01:00
parent f773e599d0
commit ba723be738
5 changed files with 165 additions and 22 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
using CoreIntegrationTests.Infrastructure; using CoreIntegrationTests.Infrastructure;
using MongoDB.Bson; using MongoDB.Bson;
using System;
namespace CoreIntegrationTests namespace CoreIntegrationTests
{ {
public class CoreObjectIdTestDocument : TestDoc<ObjectId> public class CoreObjectIdTestDocument : TestDoc<ObjectId>
@@ -0,0 +1,154 @@
using MongoDB.Driver;
using MongoDbGenericRepository.Models;
using MongoDbGenericRepository.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MongoDbGenericRepository
{
/// <summary>
/// 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.
/// </summary>
/// <typeparam name="TKey"></typeparam>
public abstract class KeyTypedBaseMongoDbRepository<TKey> : KeyTypedReadOnlyMongoRepository<TKey>, IKeyTypedReadOnlyMongoRepository<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// The constructor taking a connection string and a database name.
/// </summary>
/// <param name="connectionString">The connection string of the MongoDb server.</param>
/// <param name="databaseName">The name of the database against which you want to perform operations.</param>
protected KeyTypedBaseMongoDbRepository(string connectionString, string databaseName) : base(connectionString, databaseName)
{
}
/// <summary>
/// The contructor taking a <see cref="IMongoDbContext"/>.
/// </summary>
/// <param name="mongoDbContext">A mongodb context implementing <see cref="IMongoDbContext"/></param>
protected KeyTypedBaseMongoDbRepository(IMongoDbContext mongoDbContext) : base(mongoDbContext)
{
}
/// <summary>
/// The contructor taking a <see cref="IMongoDatabase"/>.
/// </summary>
/// <param name="mongoDatabase">A mongodb context implementing <see cref="IMongoDatabase"/></param>
protected KeyTypedBaseMongoDbRepository(IMongoDatabase mongoDatabase) : base(mongoDatabase)
{
}
#region Create
/// <summary>
/// Asynchronously adds a document to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="document">The document you want to add.</param>
public virtual async Task AddOneAsync<TDocument>(TDocument document) where TDocument : IDocument<TKey>
{
FormatDocument(document);
await HandlePartitioned(document).InsertOneAsync(document);
}
/// <summary>
/// Adds a document to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="document">The document you want to add.</param>
public virtual void AddOne<TDocument>(TDocument document) where TDocument : IDocument<TKey>
{
FormatDocument(document);
HandlePartitioned(document).InsertOne(document);
}
/// <summary>
/// Asynchronously adds a list of documents to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documents">The documents you want to add.</param>
public virtual async Task AddManyAsync<TDocument>(IEnumerable<TDocument> documents) where TDocument : IDocument<TKey>
{
if (!documents.Any())
{
return;
}
foreach (var document in documents)
{
FormatDocument(document);
}
// cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5
if (documents.Any(e => e is IPartitionedDocument))
{
foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey))
{
await HandlePartitioned(group.FirstOrDefault()).InsertManyAsync(group.ToList());
}
}
else
{
await GetCollection<TDocument>().InsertManyAsync(documents.ToList());
}
}
/// <summary>
/// Adds a list of documents to the collection.
/// Populates the Id and AddedAtUtc fields if necessary.
/// </summary>
/// <typeparam name="TDocument">The type representing a Document.</typeparam>
/// <param name="documents">The documents you want to add.</param>
public virtual void AddMany<TDocument>(IEnumerable<TDocument> documents) where TDocument : IDocument<TKey>
{
if (!documents.Any())
{
return;
}
foreach (var document in documents)
{
FormatDocument(document);
}
// cannot use typeof(IPartitionedDocument).IsAssignableFrom(typeof(TDocument)), not available in netstandard 1.5
if (documents.Any(e => e is IPartitionedDocument))
{
foreach (var group in documents.GroupBy(e => ((IPartitionedDocument)e).PartitionKey))
{
HandlePartitioned(group.FirstOrDefault()).InsertMany(group.ToList());
}
}
else
{
GetCollection<TDocument>().InsertMany(documents.ToList());
}
}
#endregion Create
/// <summary>
/// Sets the value of the document Id if it is not set already.
/// </summary>
/// <typeparam name="TDocument">The document type.</typeparam>
/// <param name="document">The document.</param>
protected void FormatDocument<TDocument>(TDocument document) where TDocument : IDocument<TKey>
{
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<TKey>();
}
}
}
}
@@ -263,7 +263,7 @@ namespace MongoDbGenericRepository
public async Task<TValue> GetMaxValueAsync<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> maxValueSelector, string partitionKey = null) public async Task<TValue> GetMaxValueAsync<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> maxValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey> where TDocument : IDocument<TKey>
{ {
return await GetMaxMongoQuery<TDocument, TValue>(filter, maxValueSelector, partitionKey).Project(maxValueSelector).FirstOrDefaultAsync(); return await GetMaxMongoQuery(filter, maxValueSelector, partitionKey).Project(maxValueSelector).FirstOrDefaultAsync();
} }
/// <summary> /// <summary>
@@ -277,7 +277,7 @@ namespace MongoDbGenericRepository
public TValue GetMaxValue<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> maxValueSelector, string partitionKey = null) public TValue GetMaxValue<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> maxValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey> where TDocument : IDocument<TKey>
{ {
return GetMaxMongoQuery<TDocument, TValue>(filter, maxValueSelector, partitionKey).Project(maxValueSelector).FirstOrDefault(); return GetMaxMongoQuery(filter, maxValueSelector, partitionKey).Project(maxValueSelector).FirstOrDefault();
} }
/// <summary> /// <summary>
@@ -291,7 +291,7 @@ namespace MongoDbGenericRepository
public virtual async Task<TValue> GetMinValueAsync<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null) public virtual async Task<TValue> GetMinValueAsync<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey> where TDocument : IDocument<TKey>
{ {
return await GetMinMongoQuery<TDocument, TValue>(filter, minValueSelector, partitionKey).Project(minValueSelector).FirstOrDefaultAsync(); return await GetMinMongoQuery(filter, minValueSelector, partitionKey).Project(minValueSelector).FirstOrDefaultAsync();
} }
/// <summary> /// <summary>
@@ -305,7 +305,7 @@ namespace MongoDbGenericRepository
public virtual TValue GetMinValue<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null) public virtual TValue GetMinValue<TDocument, TValue>(Expression<Func<TDocument, bool>> filter, Expression<Func<TDocument, TValue>> minValueSelector, string partitionKey = null)
where TDocument : IDocument<TKey> where TDocument : IDocument<TKey>
{ {
return GetMinMongoQuery<TDocument, TValue>(filter, minValueSelector, partitionKey).Project(minValueSelector).FirstOrDefault(); return GetMinMongoQuery(filter, minValueSelector, partitionKey).Project(minValueSelector).FirstOrDefault();
} }
#endregion #endregion
@@ -13,7 +13,7 @@ namespace MongoDbGenericRepository
/// The base Repository, it is meant to be inherited from by your custom custom MongoRepository implementation. /// 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. /// Its constructor must be given a connection string and a database name.
/// </summary> /// </summary>
public abstract partial class ReadOnlyMongoRepository public abstract partial class ReadOnlyMongoRepository : KeyTypedReadOnlyMongoRepository<Guid>, IReadOnlyMongoRepository
{ {
/// <summary> /// <summary>
/// The constructor taking a connection string and a database name. /// The constructor taking a connection string and a database name.
@@ -249,9 +249,9 @@ namespace MongoDbGenericRepository
where TKey : IEquatable<TKey> where TKey : IEquatable<TKey>
{ {
return await GetCollection<TDocument, TKey>(partitionKey).Find(Builders<TDocument>.Filter.Where(filter)) return await GetCollection<TDocument, TKey>(partitionKey).Find(Builders<TDocument>.Filter.Where(filter))
.SortBy(minValueSelector) .SortBy(minValueSelector)
.Limit(1) .Limit(1)
.FirstOrDefaultAsync(); .FirstOrDefaultAsync();
} }
/// <summary> /// <summary>
@@ -321,8 +321,8 @@ namespace MongoDbGenericRepository
where TKey : IEquatable<TKey> where TKey : IEquatable<TKey>
{ {
return await GetMaxMongoQuery<TDocument, TKey, TValue>(filter, maxValueSelector, partitionKey) return await GetMaxMongoQuery<TDocument, TKey, TValue>(filter, maxValueSelector, partitionKey)
.Project(maxValueSelector) .Project(maxValueSelector)
.FirstOrDefaultAsync(); .FirstOrDefaultAsync();
} }
/// <summary> /// <summary>
@@ -1,11 +0,0 @@
using System;
namespace MongoDbGenericRepository
{
/// <summary>
/// The ReadOnlyMongoRepository implements the readonly functionality of the IReadOnlyMongoRepository.
/// </summary>
public abstract partial class ReadOnlyMongoRepository : KeyTypedReadOnlyMongoRepository<Guid>, IReadOnlyMongoRepository
{
}
}