Add project files.
This commit is contained in:
252
Core.Blueprint.Mongo/Repositories/CollectionRepository.cs
Normal file
252
Core.Blueprint.Mongo/Repositories/CollectionRepository.cs
Normal file
@@ -0,0 +1,252 @@
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Driver;
|
||||
using MongoDB.Driver.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Core.Blueprint.Mongo
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods for interacting with a MongoDB collection for a specific document type.
|
||||
/// Inherits from <see cref="MongoProvider"/> and implements <see cref="ICollectionsRepository{TDocument}"/>.
|
||||
/// This class encapsulates common database operations such as querying, inserting, updating, and deleting documents.
|
||||
/// </summary>
|
||||
/// <typeparam name="TDocument">The type of document stored in the collection, which must implement <see cref="IDocument"/>.</typeparam>
|
||||
public class CollectionRepository<TDocument>(IMongoDatabase database) : ICollectionsRepository<TDocument> where TDocument : IDocument
|
||||
{
|
||||
private IMongoCollection<TDocument> _collection;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the MongoDB collection based on the <see cref="CollectionAttributeName"/> attribute
|
||||
/// applied to the <typeparamref name="TDocument"/> type. Throws an exception if the attribute is not present.
|
||||
/// </summary>
|
||||
public void CollectionInitialization()
|
||||
{
|
||||
var collectionAttribute = typeof(TDocument).GetCustomAttribute<CollectionAttributeName>();
|
||||
if (collectionAttribute == null)
|
||||
{
|
||||
throw new InvalidOperationException($"The class {typeof(TDocument).Name} is missing the CollectionAttributeName attribute.");
|
||||
}
|
||||
|
||||
string collectionName = collectionAttribute.Name;
|
||||
|
||||
_collection = database.GetCollection<TDocument>(collectionName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all documents from the collection as an enumerable list.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains an enumerable list of documents.</returns>
|
||||
public virtual async ValueTask<IEnumerable<TDocument>> AsQueryable()
|
||||
{
|
||||
return await _collection.AsQueryable().ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters documents in the collection based on the provided filter expression.
|
||||
/// </summary>
|
||||
/// <param name="filterExpression">A lambda expression that defines the filter criteria for the documents.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains a list of documents that match the filter.</returns>
|
||||
public virtual async Task<IEnumerable<TDocument>> FilterBy(
|
||||
Expression<Func<TDocument, bool>> filterExpression)
|
||||
{
|
||||
var objectResult = await _collection.FindAsync(filterExpression).ConfigureAwait(false);
|
||||
return objectResult.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters documents in the collection based on the provided filter and projection expressions.
|
||||
/// Projects the filtered documents into a new type.
|
||||
/// </summary>
|
||||
/// <typeparam name="TProjected">The type to project the documents into.</typeparam>
|
||||
/// <param name="filterExpression">A lambda expression that defines the filter criteria for the documents.</param>
|
||||
/// <param name="projectionExpression">A lambda expression that defines how the documents should be projected.</param>
|
||||
/// <returns>An enumerable collection of projected documents.</returns>
|
||||
public virtual IEnumerable<TProjected> FilterBy<TProjected>(
|
||||
Expression<Func<TDocument, bool>> filterExpression,
|
||||
Expression<Func<TDocument, TProjected>> projectionExpression)
|
||||
{
|
||||
return _collection.Find(filterExpression).Project(projectionExpression).ToEnumerable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a single document that matches the provided filter expression.
|
||||
/// </summary>
|
||||
/// <param name="filterExpression">A lambda expression that defines the filter criteria for the document.</param>
|
||||
/// <returns>The document that matches the filter, or <c>null</c> if no document is found.</returns>
|
||||
public virtual TDocument FindOne(Expression<Func<TDocument, bool>> filterExpression)
|
||||
{
|
||||
return _collection.Find(filterExpression).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters documents in the collection based on the provided MongoDB filter definition.
|
||||
/// </summary>
|
||||
/// <param name="filterDefinition">A filter definition for MongoDB query.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains a list of documents that match the filter.</returns>
|
||||
public virtual async Task<IEnumerable<TDocument>> FilterByMongoFilterAsync(FilterDefinition<TDocument> filterDefinition)
|
||||
{
|
||||
var objectResult = await _collection.Find(filterDefinition).ToListAsync().ConfigureAwait(false);
|
||||
return objectResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously finds a single document that matches the provided filter expression.
|
||||
/// </summary>
|
||||
/// <param name="filterExpression">A lambda expression that defines the filter criteria for the document.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains the document that matches the filter, or <c>null</c> if no document is found.</returns>
|
||||
public virtual Task<TDocument> FindOneAsync(Expression<Func<TDocument, bool>> filterExpression)
|
||||
{
|
||||
return Task.Run(() => _collection.Find(filterExpression).FirstOrDefaultAsync());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a document by its unique identifier (ID).
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the document.</param>
|
||||
/// <returns>The document that matches the specified ID, or <c>null</c> if no document is found.</returns>
|
||||
public virtual TDocument FindById(string id)
|
||||
{
|
||||
var filter = Builders<TDocument>.Filter.Eq(doc => doc._Id, id);
|
||||
return _collection.Find(filter).SingleOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously finds a document by its unique identifier (ID).
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the document.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains the document that matches the specified ID, or <c>null</c> if no document is found.</returns>
|
||||
public virtual Task<TDocument> FindByIdAsync(string id)
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
var objectId = new ObjectId(id);
|
||||
var filter = Builders<TDocument>.Filter.Eq(doc => doc._Id, id);
|
||||
return _collection.Find(filter).SingleOrDefaultAsync();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a single document into the collection.
|
||||
/// </summary>
|
||||
/// <param name="document">The document to insert.</param>
|
||||
public virtual void InsertOne(TDocument document)
|
||||
{
|
||||
_collection.InsertOne(document);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously inserts a single document into the collection.
|
||||
/// </summary>
|
||||
/// <param name="document">The document to insert.</param>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
public virtual Task InsertOneAsync(TDocument document)
|
||||
{
|
||||
return Task.Run(() => _collection.InsertOneAsync(document));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts multiple documents into the collection.
|
||||
/// </summary>
|
||||
/// <param name="documents">The collection of documents to insert.</param>
|
||||
public void InsertMany(ICollection<TDocument> documents)
|
||||
{
|
||||
_collection.InsertMany(documents);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously inserts multiple documents into the collection.
|
||||
/// </summary>
|
||||
/// <param name="documents">The collection of documents to insert.</param>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
public virtual async Task InsertManyAsync(ICollection<TDocument> documents)
|
||||
{
|
||||
await _collection.InsertManyAsync(documents);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces an existing document in the collection.
|
||||
/// </summary>
|
||||
/// <param name="document">The document with the updated data.</param>
|
||||
public void ReplaceOne(TDocument document)
|
||||
{
|
||||
var filter = Builders<TDocument>.Filter.Eq(doc => doc._Id, document._Id);
|
||||
_collection.FindOneAndReplace(filter, document);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously replaces an existing document in the collection.
|
||||
/// </summary>
|
||||
/// <param name="document">The document with the updated data.</param>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
public virtual async Task ReplaceOneAsync(TDocument document)
|
||||
{
|
||||
var filter = Builders<TDocument>.Filter.Eq(doc => doc._Id, document._Id);
|
||||
await _collection.FindOneAndReplaceAsync(filter, document);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a single document from the collection based on the provided filter expression.
|
||||
/// </summary>
|
||||
/// <param name="filterExpression">A lambda expression that defines the filter criteria for the document to delete.</param>
|
||||
public void DeleteOne(Expression<Func<TDocument, bool>> filterExpression)
|
||||
{
|
||||
_collection.FindOneAndDelete(filterExpression);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously deletes a single document from the collection based on the provided filter expression.
|
||||
/// </summary>
|
||||
/// <param name="filterExpression">A lambda expression that defines the filter criteria for the document to delete.</param>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
public async Task<TDocument> DeleteOneAsync(Expression<Func<TDocument, bool>> filterExpression)
|
||||
{
|
||||
return await _collection.FindOneAndDeleteAsync(filterExpression);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a single document from the collection based on its unique identifier (ID).
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the document to delete.</param>
|
||||
public void DeleteById(string id)
|
||||
{
|
||||
var objectId = new ObjectId(id);
|
||||
var filter = Builders<TDocument>.Filter.Eq(doc => doc._Id, id);
|
||||
_collection.FindOneAndDelete(filter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously deletes a single document from the collection based on its unique identifier (ID).
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the document to delete.</param>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
public Task DeleteByIdAsync(string id)
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
var objectId = new ObjectId(id);
|
||||
var filter = Builders<TDocument>.Filter.Eq(doc => doc._Id, id);
|
||||
_collection.FindOneAndDeleteAsync(filter);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes multiple documents from the collection based on the provided filter expression.
|
||||
/// </summary>
|
||||
/// <param name="filterExpression">A lambda expression that defines the filter criteria for the documents to delete.</param>
|
||||
public void DeleteMany(Expression<Func<TDocument, bool>> filterExpression)
|
||||
{
|
||||
_collection.DeleteMany(filterExpression);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously deletes multiple documents from the collection based on the provided filter expression.
|
||||
/// </summary>
|
||||
/// <param name="filterExpression">A lambda expression that defines the filter criteria for the documents to delete.</param>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
public Task DeleteManyAsync(Expression<Func<TDocument, bool>> filterExpression)
|
||||
{
|
||||
return Task.Run(() => _collection.DeleteManyAsync(filterExpression));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user