Standard Implementation of REN Repository
Here is the standard implementation of RENRepository which allows you to use pre-defined Repository:
INTERFACE:
public interface IRENRepository<TEntity> where TEntity : class
{
#region Create
/// <summary>
/// Inserts a single entity into the repository.
/// </summary>
/// <param name="entity">The entity to insert.</param>
void Insert(TEntity entity);
/// <summary>
/// Inserts a single entity into the repository asynchronously.
/// </summary>
/// <param name="entity">The entity to insert asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
Task InsertAsync(TEntity entity, CancellationToken cancellationToken = default);
/// <summary>
/// Inserts list of entities into the repository.
/// </summary>
/// <param name="entities">The entity list to insert.</param>
void Insert(IEnumerable<TEntity> entities);
/// <summary>
/// Inserts list of entities into the repository asynchronously.
/// </summary>
/// <param name="entities">The entity list to insert asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
Task InsertAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default);
/// <summary>
/// Bulk inserts a list of entities into the repository.
/// </summary>
/// <param name="entities">The list of entities to insert.</param>
void BulkInsert(IEnumerable<TEntity> entities, BulkConfig? bulkConfig = null);
/// <summary>
/// Bulk inserts a list of entities into the repository asynchronously.
/// </summary>
/// <param name="entities">The list of entities to insert asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
Task BulkInsertAsync(IEnumerable<TEntity> entities, BulkConfig? bulkConfig = null, CancellationToken cancellationToken = default);
#endregion
#region Read
/// <summary>
/// Gets a queryable collection of entities from the repository.
/// </summary>
/// <param name="filter">An optional filter expression.</param>
/// <param name="orderBy">An optional ordering expression.</param>
/// <param name="include">An optional include expression.</param>
/// <param name="isReadOnly">A flag indicating if the query is read-only.</param>
/// <returns>A queryable collection of entities.</returns>
IQueryable<TEntity> GetQueryable(Expression<Func<TEntity, bool>>? filter = null,
Expression<Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>>? orderBy = null,
Expression<Func<IQueryable<TEntity>, IQueryable<TEntity>>>? include = null, bool isReadOnly = false);
/// <summary>
/// Gets a queryable collection of entities from the repository asynchronously.
/// </summary>
/// <param name="filter">An optional filter expression.</param>
/// <param name="orderBy">An optional ordering expression.</param>
/// <param name="include">An optional include expression.</param>
/// <param name="isReadOnly">A flag indicating if the query is read-only.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the queryable collection of entities.</returns>
Task<IQueryable<TEntity>> GetQueryableAsync(Expression<Func<TEntity, bool>>? filter = null,
Expression<Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>>? orderBy = null,
Expression<Func<IQueryable<TEntity>, IQueryable<TEntity>>>? include = null, bool isReadOnly = false,
CancellationToken cancellationToken = default);
/// <summary>
/// Gets a list of entities from the repository.
/// </summary>
/// <param name="filter">An optional filter expression.</param>
/// <param name="orderBy">An optional ordering expression.</param>
/// <param name="include">An optional include expression.</param>
/// <param name="isReadOnly">A flag indicating if the query is read-only.</param>
/// <returns>A list of entities.</returns>
List<TEntity> GetList(Expression<Func<TEntity, bool>>? filter = null,
Expression<Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>>? orderBy = null,
Expression<Func<IQueryable<TEntity>, IQueryable<TEntity>>>? include = null, bool isReadOnly = false);
/// <summary>
/// Gets a list of entities from the repository asynchronously.
/// </summary>
/// <param name="filter">An optional filter expression.</param>
/// <param name="orderBy">An optional ordering expression.</param>
/// <param name="include">An optional include expression.</param>
/// <param name="isReadOnly">A flag indicating if the query is read-only.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the list of entities.</returns>
Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>>? filter = null,
Expression<Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>>? orderBy = null,
Expression<Func<IQueryable<TEntity>, IQueryable<TEntity>>>? include = null, bool isReadOnly = false,
CancellationToken cancellationToken = default);
/// <summary>
/// Gets a single entity from the repository.
/// </summary>
/// <param name="filter">Required filter expression.</param>
/// <param name="include">An optional include expression.</param>
/// <param name="isReadOnly">A flag indicating if the query is read-only.</param>
/// <returns>A single entity or null if not found.</returns>
TEntity? GetSingle(Expression<Func<TEntity, bool>> filter,
Expression<Func<IQueryable<TEntity>, IQueryable<TEntity>>>? include = null,
bool isReadOnly = false);
/// <summary>
/// Gets a single entity from the repository asynchronously.
/// </summary>
/// <param name="filter">Required filter expression.</param>
/// <param name="include">An optional include expression.</param>
/// <param name="isReadOnly">A flag indicating if the query is read-only.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the single entity or null if not found.</returns>
Task<TEntity?> GetSingleAsync(Expression<Func<TEntity, bool>> filter,
Expression<Func<IQueryable<TEntity>, IQueryable<TEntity>>>? include = null,
bool isReadOnly = false,
CancellationToken cancellationToken = default);
#endregion
#region Update
/// <summary>
/// Updates a single entity in the repository.
/// </summary>
/// <param name="entity">The entity to update.</param>
void Update(TEntity entity);
/// <summary>
/// Updates a single entity in the repository asynchronously.
/// </summary>
/// <param name="entity">The entity to update asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default);
/// <summary>
/// Bulk updates multiple entities in the repository.
/// </summary>
/// <param name="entity">The entities to update.</param>
void BulkUpdate(IEnumerable<TEntity> entities, BulkConfig? bulkConfig = null);
/// <summary>
/// Bulk updates multiple entities in the repository asynchronously.
/// </summary>
/// <param name="entity">The entities to update asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
Task BulkUpdateAsync(IEnumerable<TEntity> entities, BulkConfig? bulkConfig = null, CancellationToken cancellationToken = default);
#endregion
#region Delete
/// <summary>
/// Deletes a single entity from the repository.
/// </summary>
/// <param name="entity">The entity to delete.</param>
void Delete(TEntity entity);
/// <summary>
/// Deletes a single entity from the repository asynchronously.
/// </summary>
/// <param name="entity">The entity to delete asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default);
/// <summary>
/// Deletes a list of entities from the database.
/// </summary>
/// <param name="entities">The list of entities to delete.</param>
void Delete(IEnumerable<TEntity> entities);
/// <summary>
/// Deletes a list of entities from the database asynchronously.
/// </summary>
/// <param name="entities">The list of entities to delete asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
Task DeleteAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default);
/// <summary>
/// Bulk deletes a list of entities from the repository.
/// </summary>
/// <param name="entities">The list of entities to delete asynchronously.</param>{{}
void BulkDelete(IEnumerable<TEntity> entities, BulkConfig? bulkConfig = null);
/// <summary>
/// Bulk deletes a list of entities from the repository asynchronously.
/// </summary>
/// <param name="entities">The list of entities to delete asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
Task BulkDeleteAsync(IEnumerable<TEntity> entities, BulkConfig? bulkConfig = null, CancellationToken cancellationToken = default);
#endregion
}
CLASS:
public class RENRepository<TEntity> : IRENRepository<TEntity> where TEntity : class
{
private readonly DbContext _context;
private readonly DbSet<TEntity> _dbSet;
/// <summary>
/// Initializes a new instance of the <see cref="RENRepository{TEntity}" /> class.
/// </summary>
/// <param name="context">The database context.</param>
public RENRepository(DbContext context)
{
_context = context ?? throw new ArgumentNullException("context");
_dbSet = context.Set<TEntity>();
}
#region Create
/// <summary>
/// Inserts a single entity into the database.
/// </summary>
/// <param name="entity">The entity to insert.</param>
public virtual void Insert(TEntity entity)
{
_dbSet.Add(entity);
}
/// <summary>
/// Inserts a single entity into the database asynchronously.
/// </summary>
/// <param name="entity">The entity to insert asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
public virtual async Task InsertAsync(TEntity entity, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
await _dbSet.AddAsync(entity, cancellationToken);
}
/// <summary>
/// Inserts a list of entities into the database.
/// </summary>
/// <param name="entities">The list of entities to insert.</param>
public virtual void Insert(IEnumerable<TEntity> entities)
{
_dbSet.AddRange(entities);
}
/// <summary>
/// Inserts a list of entities into the database asynchronously.
/// </summary>
/// <param name="entities">The list of entities to insert asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
public virtual async Task InsertAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
await _dbSet.AddRangeAsync(entities, cancellationToken);
}
/// <summary>
/// Bulk inserts a list of entities into the repository.
/// </summary>
/// <param name="entities">The list of entities to insert.</param>
public virtual void BulkInsert(IEnumerable<TEntity> entities, BulkConfig? bulkConfig = null)
{
bulkConfig ??= new BulkConfig();
_context.BulkInsert(entities, bulkConfig);
}
/// <summary>
/// Bulk inserts a list of entities into the repository asynchronously.
/// </summary>
/// <param name="entities">The list of entities to insert asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
public virtual async Task BulkInsertAsync(IEnumerable<TEntity> entities, BulkConfig? bulkConfig = null, CancellationToken cancellationToken = default)
{
bulkConfig ??= new BulkConfig();
await _context.BulkInsertAsync(entities, bulkConfig, cancellationToken: cancellationToken);
}
#endregion
#region Read
/// <summary>
/// Gets a queryable collection of entities from the database.
/// </summary>
/// <param name="filter">An optional filter expression.</param>
/// <param name="orderBy">An optional ordering expression.</param>
/// <param name="include">An optional include expression.</param>
/// <param name="isReadOnly">A flag indicating if the query is read-only.</param>
/// <returns>A queryable collection of entities.</returns>
public virtual IQueryable<TEntity> GetQueryable(Expression<Func<TEntity, bool>>? filter = null,
Expression<Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>>? orderBy = null,
Expression<Func<IQueryable<TEntity>, IQueryable<TEntity>>>? include = null, bool isReadOnly = false)
{
IQueryable<TEntity> query = _dbSet;
if (include != null)
{
query = include.Compile().Invoke(query);
}
if (isReadOnly)
query = query.AsNoTracking();
if (filter != null)
query = query.Where(filter);
return orderBy != null ? orderBy.Compile().Invoke(query) : query;
}
/// <summary>
/// Gets a queryable collection of entities from the database asynchronously.
/// </summary>
/// <param name="filter">An optional filter expression.</param>
/// <param name="orderBy">An optional ordering expression.</param>
/// <param name="include">An optional include expression.</param>
/// <param name="isReadOnly">A flag indicating if the query is read-only.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the queryable collection of entities.</returns>
public virtual Task<IQueryable<TEntity>> GetQueryableAsync(Expression<Func<TEntity, bool>>? filter = null,
Expression<Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>>? orderBy = null,
Expression<Func<IQueryable<TEntity>, IQueryable<TEntity>>>? include = null, bool isReadOnly = false, CancellationToken cancellationToken = default)
{
return Task.Factory.StartNew(() =>
{
cancellationToken.ThrowIfCancellationRequested();
IQueryable<TEntity> query = _dbSet;
if (include != null)
{
query = include.Compile().Invoke(query);
}
if (isReadOnly)
query = query.AsNoTracking();
if (filter != null)
query = query.Where(filter);
return orderBy != null ? orderBy.Compile().Invoke(query) : query;
}, cancellationToken);
}
/// <summary>
/// Gets a list of entities from the database.
/// </summary>
/// <param name="filter">An optional filter expression.</param>
/// <param name="orderBy">An optional ordering expression.</param>
/// <param name="include">An optional include expression.</param>
/// <param name="isReadOnly">A flag indicating if the query is read-only.</param>
/// <returns>A list of entities.</returns>
public virtual List<TEntity> GetList(Expression<Func<TEntity, bool>>? filter = null,
Expression<Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>>? orderBy = null,
Expression<Func<IQueryable<TEntity>, IQueryable<TEntity>>>? include = null, bool isReadOnly = false)
{
return GetQueryable(filter, orderBy, include, isReadOnly).ToList();
}
/// <summary>
/// Gets a list of entities from the database asynchronously.
/// </summary>
/// <param name="filter">An optional filter expression.</param>
/// <param name="orderBy">An optional ordering expression.</param>
/// <param name="include">An optional include expression.</param>
/// <param name="isReadOnly">A flag indicating if the query is read-only.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the list of entities.</returns>
public virtual Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>>? filter = null,
Expression<Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>>? orderBy = null,
Expression<Func<IQueryable<TEntity>, IQueryable<TEntity>>>? include = null, bool isReadOnly = false, CancellationToken cancellationToken = default)
{
return GetQueryableAsync(filter, orderBy, include, isReadOnly, cancellationToken).Result.ToListAsync(cancellationToken);
}
/// <summary>
/// Gets a single entity from the database.
/// </summary>
/// <param name="filter">Required filter expression.</param>
/// <param name="include">An optional include expression.</param>
/// <param name="isReadOnly">A flag indicating if the query is read-only.</param>
/// <returns>A single entity or null if not found.</returns>
public virtual TEntity? GetSingle(Expression<Func<TEntity, bool>> filter,
Expression<Func<IQueryable<TEntity>, IQueryable<TEntity>>>? include = null,
bool isReadOnly = false)
{
return GetQueryable(filter, null, include, isReadOnly).SingleOrDefault();
}
/// <summary>
/// Gets a single entity from the database asynchronously.
/// </summary>
/// <param name="filter">Required filter expression.</param>
/// <param name="include">An optional include expression.</param>
/// <param name="isReadOnly">A flag indicating if the query is read-only.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the single entity or null if not found.</returns>
public virtual Task<TEntity?> GetSingleAsync(Expression<Func<TEntity, bool>> filter,
Expression<Func<IQueryable<TEntity>, IQueryable<TEntity>>>? include = null,
bool isReadOnly = false,
CancellationToken cancellationToken = default)
{
return GetQueryableAsync(filter, null, include, isReadOnly, cancellationToken).Result.SingleOrDefaultAsync(cancellationToken);
}
#endregion
#region Update
/// <summary>
/// Updates a single entity in the database.
/// </summary>
/// <param name="entity">The entity to update.</param>
public virtual void Update(TEntity entity)
{
_context.Entry(entity).State = EntityState.Modified;
}
/// <summary>
/// Updates a single entity in the database asynchronously.
/// </summary>
/// <param name="entity">The entity to update asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
public virtual Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default)
{
return Task.Factory.StartNew(() =>
{
cancellationToken.ThrowIfCancellationRequested();
_context.Entry(entity).State = EntityState.Modified;
}, cancellationToken);
}
/// <summary>
/// Bulk updates multiple entities in the repository.
/// </summary>
/// <param name="entity">The entities to update.</param>
public virtual void BulkUpdate(IEnumerable<TEntity> entities, BulkConfig? bulkConfig = null)
{
bulkConfig ??= new BulkConfig();
_context.BulkUpdate(entities, bulkConfig);
}
/// <summary>
/// Bulk updates multiple entities in the repository asynchronously.
/// </summary>
/// <param name="entity">The entities to update asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
public virtual async Task BulkUpdateAsync(IEnumerable<TEntity> entities, BulkConfig? bulkConfig = null, CancellationToken cancellationToken = default)
{
bulkConfig ??= new BulkConfig();
await _context.BulkUpdateAsync(entities, bulkConfig, cancellationToken: cancellationToken);
}
#endregion
#region Delete
/// <summary>
/// Deletes a single entity from the database.
/// </summary>
/// <param name="entity">The entity to delete.</param>
public virtual void Delete(TEntity entity)
{
_dbSet.Remove(entity);
}
/// <summary>
/// Deletes a single entity from the database asynchronously.
/// </summary>
/// <param name="entity">The entity to delete asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
public virtual Task DeleteAsync(TEntity entity, CancellationToken cancellationToken = default)
{
return Task.Factory.StartNew(() =>
{
cancellationToken.ThrowIfCancellationRequested();
return _dbSet.Remove(entity);
}, cancellationToken);
}
/// <summary>
/// Deletes a list of entities from the database.
/// </summary>
/// <param name="entities">The list of entities to delete.</param>
public virtual void Delete(IEnumerable<TEntity> entities)
{
_dbSet.RemoveRange(entities);
}
/// <summary>
/// Deletes a list of entities from the database asynchronously.
/// </summary>
/// <param name="entities">The list of entities to delete asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
public virtual Task DeleteAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default)
{
return Task.Factory.StartNew(() =>
{
cancellationToken.ThrowIfCancellationRequested();
_dbSet.RemoveRange(entities);
}, cancellationToken);
}
/// <summary>
/// Bulk deletes a list of entities from the repository.
/// </summary>
/// <param name="entities">The list of entities to delete asynchronously.</param>{{}
public virtual void BulkDelete(IEnumerable<TEntity> entities, BulkConfig? bulkConfig = null)
{
bulkConfig ??= new BulkConfig();
_context.BulkDelete(entities, bulkConfig);
}
/// <summary>
/// Bulk deletes a list of entities from the repository asynchronously.
/// </summary>
/// <param name="entities">The list of entities to delete asynchronously.</param>
/// <param name="cancellationToken">Optional cancellationToken.</param>
/// <returns>A task representing the asynchronous operation.</returns>
public virtual async Task BulkDeleteAsync(IEnumerable<TEntity> entities, BulkConfig? bulkConfig = null, CancellationToken cancellationToken = default)
{
bulkConfig ??= new BulkConfig();
await _context.BulkDeleteAsync(entities, bulkConfig, cancellationToken: cancellationToken);
}
#endregion
}
Here, you can see all methods are defined as virtual which allows you to override them if necessary according to your needs. To use this pre-defined methods, you don't need to register them in Program.cs file since they can be produced within the GetRENRepository function in RENUnitOfWork
You can use RENRepositories like this:
public class HomeController : ControllerBase
{
private readonly IRENRepository<User> _userRepository;
public HomeController(IMyUnitOfWork<RENDbContext> uow)
{
_userRepository = _uow.GetRENRepository<User>();
}
[HttpGet, Route("GetUsers")]
public async Task<IActionResult> SideIndex()
{
var users = await _userRepository.GetListAsync();
return Ok(users);
}
}
Last updated