257 lines
15 KiB
C#
257 lines
15 KiB
C#
|
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);
|
|||
|
}
|
|||
|
}
|