zeroframework/Services/DeviceCenter/ZeroFramework.DeviceCenter.Domain/Repositories/IRepository.cs

257 lines
15 KiB
C#
Raw Normal View History

2023-12-05 09:22:48 +00:00
using System.Linq.Expressions;
using ZeroFramework.DeviceCenter.Domain.Specifications;
using ZeroFramework.DeviceCenter.Domain.UnitOfWork;
namespace ZeroFramework.DeviceCenter.Domain.Repositories
{
public interface IRepository<TEntity>
{
/// <summary>
/// Inserts a new entity.
/// </summary>
/// <param name="autoSave">
/// Set true to automatically save changes to database.
/// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database.
/// </param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <param name="entity">Inserted entity</param>
Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default);
/// <summary>
/// Inserts multiple new entities.
/// </summary>
/// <param name="autoSave">
/// Set true to automatically save changes to database.
/// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database.
/// </param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <param name="entities">Entities to be inserted.</param>
/// <returns>Awaitable <see cref="Task"/>.</returns>
Task InsertManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default);
/// <summary>
/// Updates an existing entity.
/// </summary>
/// <param name="autoSave">
/// Set true to automatically save changes to database.
/// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database.
/// </param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <param name="entity">Entity</param>
Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default);
/// <summary>
/// Updates multiple entities.
/// </summary>
/// <param name="entities">Entities to be updated.</param>
/// <param name="autoSave">
/// Set true to automatically save changes to database.
/// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database.</param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>Awaitable <see cref="Task"/>.</returns>
Task UpdateManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default);
/// <summary>
/// Deletes an entity.
/// </summary>
/// <param name="entity">Entity to be deleted</param>
/// <param name="autoSave">
/// Set true to automatically save changes to database.
/// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database.
/// </param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default);
/// <summary>
/// Deletes many entities by function.
/// Notice that: All entities fits to given predicate are retrieved and deleted.
/// This may cause major performance problems if there are too many entities with
/// given predicate.
/// </summary>
/// <param name="predicate">A condition to filter entities</param>
/// <param name="autoSave">
/// Set true to automatically save changes to database.
/// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database.
/// </param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, bool autoSave = false, CancellationToken cancellationToken = default);
/// <summary>
/// Deletes multiple entities.
/// </summary>
/// <param name="entities">Entities to be deleted.</param>
/// <param name="autoSave">
/// Set true to automatically save changes to database.
/// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database.
/// </param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>Awaitable <see cref="Task"/>.</returns>
Task DeleteManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default);
/// <summary>
/// Gets a list of all the entities.
/// </summary>
/// <param name="includeDetails">Set true to include all children of this entity</param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>Entity</returns>
Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default);
/// <summary>
/// Gets total count of all entities.
/// </summary>
Task<long> GetCountAsync(CancellationToken cancellationToken = default);
/// <summary>
/// Gets a list of paged the entities.
/// </summary>
Task<List<TEntity>> GetListAsync(int pageNumber, int pageSize, Expression<Func<TEntity, object>> sorting, bool includeDetails = false, CancellationToken cancellationToken = default);
#region Related Navigation Property
/// <summary>
/// Specifies related entities to include in the query results. The navigation property to be included is specified starting with the type of entity being queried.
/// </summary>
Task<IQueryable<TEntity>> IncludeRelatedAsync(params Expression<Func<TEntity, object?>>[] propertySelectors);
/// <summary>
/// Provides access to change tracking and loading information for a collection navigation property that associates this entity to a collection of another entities.
/// </summary>
Task LoadRelatedAsync<TProperty>(TEntity entity, Expression<Func<TEntity, IEnumerable<TProperty>>> propertyExpression, CancellationToken cancellationToken = default) where TProperty : class;
/// <summary>
/// Provides access to change tracking and loading information for a reference (i.e. non-collection) navigation property that associates this entity to another entity.
/// </summary>
Task LoadRelatedAsync<TProperty>(TEntity entity, Expression<Func<TEntity, TProperty?>> propertyExpression, CancellationToken cancellationToken = default) where TProperty : class;
#endregion
/// <summary>
/// Get a single entity by the given <paramref name="predicate"/>.
/// It returns null if no entity with the given <paramref name="predicate"/>.
/// It throws <see cref="InvalidOperationException"/> if there are multiple entities with the given <paramref name="predicate"/>.
/// </summary>
/// <param name="predicate">A condition to find the entity</param>
/// <param name="includeDetails">Set true to include all children of this entity</param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
Task<TEntity?> FindAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = true, CancellationToken cancellationToken = default);
/// <summary>
/// Get a single entity by the given <paramref name="predicate"/>.
/// It throws <see cref="EntityNotFoundException"/> if there is no entity with the given <paramref name="predicate"/>.
/// It throws <see cref="InvalidOperationException"/> if there are multiple entities with the given <paramref name="predicate"/>.
/// </summary>
/// <param name="predicate">A condition to filter entities</param>
/// <param name="includeDetails">Set true to include all children of this entity</param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = true, CancellationToken cancellationToken = default);
#region Specification Pattern
/// <summary>
/// Filters the entities of <typeparamref name="T"/>, to those that match the encapsulated query logic of the
/// <paramref name="specification"/>.
/// </summary>
/// <param name="specification">The encapsulated query logic.</param>
/// <returns>The filtered entities as an <see cref="IQueryable{T}"/>.</returns>
IQueryable<TEntity> ApplySpecification(ISpecification<TEntity> specification);
/// <summary>
/// Filters all entities of <typeparamref name="T" />, that matches the encapsulated query logic of the
/// <paramref name="specification"/>, from the database.
/// <para>
/// Projects each entity into a new form, being <typeparamref name="TResult" />.
/// </para>
/// </summary>
/// <typeparam name="TResult">The type of the value returned by the projection.</typeparam>
/// <param name="specification">The encapsulated query logic.</param>
/// <returns>The filtered projected entities as an <see cref="IQueryable{T}"/>.</returns>
IQueryable<TResult> ApplySpecification<TResult>(ISpecification<TEntity, TResult> specification);
/// <summary>
/// Gets a list of specification the entities.
/// </summary>
Task<List<TEntity>> GetListAsync(ISpecification<TEntity> specification, CancellationToken cancellationToken = default);
/// <summary>
/// Gets a list of specification the entities.
/// </summary>
Task<List<TResult>> GetListAsync<TResult>(ISpecification<TEntity, TResult> specification, CancellationToken cancellationToken = default);
/// <summary>
/// Gets total count of all entities.
/// </summary>
Task<long> GetCountAsync(ISpecification<TEntity> specification, CancellationToken cancellationToken = default);
/// <summary>
/// Get a single entity by the given
/// </summary>
Task<TEntity> GetAsync(ISpecification<TEntity> specification, CancellationToken cancellationToken = default);
/// <summary>
/// Get a single entity by the given
/// </summary>
Task<TResult> GetAsync<TResult>(ISpecification<TEntity, TResult> specification, CancellationToken cancellationToken = default);
#endregion
/// <summary>
/// Provides functionality to evaluate queries against a specific data source wherein the type of the data is known.
/// </summary>
IQueryable<TEntity> Query { get; }
/// <summary>
///LINQ related extension methods.
/// </summary>
IAsyncQueryableProvider AsyncExecuter { get; }
/// <summary>
///Using the Repository and Unit Of Work Pattern
/// </summary>
IUnitOfWork UnitOfWork { get; }
}
public interface IRepository<TEntity, TKey> : IRepository<TEntity>
{
/// <summary>
/// Deletes an entity by primary key.
/// </summary>
/// <param name="id">Primary key of the entity</param>
/// <param name="autoSave">
/// Set true to automatically save changes to database.
/// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database.
/// </param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default); //TODO: Return true if deleted
/// <summary>
/// Deletes multiple entities by primary keys.
/// </summary>
/// <param name="ids">Primary keys of the each entity.</param>
/// <param name="autoSave">
/// Set true to automatically save changes to database.
/// This is useful for ORMs / database APIs those only save changes with an explicit method call, but you need to immediately save changes to the database.
/// </param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>Awaitable <see cref="Task"/>.</returns>
Task DeleteManyAsync(IEnumerable<TKey> ids, bool autoSave = false, CancellationToken cancellationToken = default);
/// <summary>
/// Gets an entity with given primary key.
/// Throws <see cref="EntityNotFoundException"/> if can not find an entity with given id.
/// </summary>
/// <param name="id">Primary key of the entity to get</param>
/// <param name="includeDetails">Set true to include all children of this entity</param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>Entity</returns>
Task<TEntity> GetAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default);
/// <summary>
/// Gets an entity with given primary key or null if not found.
/// </summary>
/// <param name="id">Primary key of the entity to get</param>
/// <param name="includeDetails">Set true to include all children of this entity</param>
/// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> to observe while waiting for the task to complete.</param>
/// <returns>Entity or null</returns>
Task<TEntity?> FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default);
}
}