183 lines
7.3 KiB
C#
183 lines
7.3 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using System.Linq.Expressions;
|
|
|
|
namespace Core.Blueprint.DAL.SQLServer
|
|
{
|
|
/// <summary>
|
|
/// The <see cref="EntityRepository{TEntity, TContext}"/> class provides a comprehensive generic repository
|
|
/// for managing entities using Entity Framework Core with SQL Server as the underlying database.
|
|
/// Designed as a package for consumption by external applications.
|
|
/// </summary>
|
|
/// <typeparam name="TEntity">The entity type managed by the repository. Must be a class.</typeparam>
|
|
/// <typeparam name="TContext">The database context type. Must inherit from <see cref="DbContext"/>.</typeparam>
|
|
public class EntityRepository<TEntity, TContext> : IEntityRepository<TEntity, TContext>
|
|
where TEntity : class
|
|
where TContext : DbContext
|
|
{
|
|
private readonly TContext _context;
|
|
private readonly DbSet<TEntity> _dbSet;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="EntityRepository{TEntity, TContext}"/> class with a specified database context.
|
|
/// </summary>
|
|
/// <param name="context">The <see cref="TContext"/> for database operations.</param>
|
|
public EntityRepository(TContext context)
|
|
{
|
|
_context = context;
|
|
_dbSet = _context.Set<TEntity>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves all entities of type <typeparamref name="TEntity"/> from the database.
|
|
/// </summary>
|
|
/// <returns>A task representing the asynchronous operation, with a list of entities as the result.</returns>
|
|
public async Task<IEnumerable<TEntity>> GetAllAsync()
|
|
{
|
|
return await _dbSet.ToListAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves all entities of type <typeparamref name="TEntity"/> from the database that match a specified filter.
|
|
/// </summary>
|
|
/// <param name="predicate">An expression to filter entities.</param>
|
|
/// <returns>A task representing the asynchronous operation, with a list of filtered entities as the result.</returns>
|
|
public async Task<IEnumerable<TEntity>> GetByConditionAsync(Expression<Func<TEntity, bool>> predicate)
|
|
{
|
|
return await _dbSet.Where(predicate).ToListAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves a single entity of type <typeparamref name="TEntity"/> by its identifier.
|
|
/// </summary>
|
|
/// <param name="id">The identifier of the entity.</param>
|
|
/// <returns>A task representing the asynchronous operation, with the entity as the result, or null if not found.</returns>
|
|
public async Task<TEntity?> GetByIdAsync(int id)
|
|
{
|
|
var existingEntity = await _dbSet.FindAsync(id);
|
|
|
|
if (existingEntity != null)
|
|
{
|
|
_context.Entry(existingEntity).State = EntityState.Detached;
|
|
}
|
|
|
|
return existingEntity;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a new entity to the database.
|
|
/// </summary>
|
|
/// <param name="entity">The entity to add.</param>
|
|
/// <returns>A task representing the asynchronous operation.</returns>
|
|
public async Task AddAsync(TEntity entity)
|
|
{
|
|
await _dbSet.AddAsync(entity);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds multiple entities to the database.
|
|
/// </summary>
|
|
/// <param name="entities">The collection of entities to add.</param>
|
|
/// <returns>A task representing the asynchronous operation.</returns>
|
|
public async Task AddRangeAsync(IEnumerable<TEntity> entities)
|
|
{
|
|
await _dbSet.AddRangeAsync(entities);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates an existing entity in the database.
|
|
/// </summary>
|
|
/// <param name="entity">The entity to update.</param>
|
|
/// <returns>The updated entity.</returns>
|
|
public TEntity Update(TEntity entity)
|
|
{
|
|
_dbSet.Attach(entity);
|
|
_context.Entry(entity).State = EntityState.Modified;
|
|
return entity;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates multiple entities in the database.
|
|
/// </summary>
|
|
/// <param name="entities">The collection of entities to update.</param>
|
|
public void UpdateRange(IEnumerable<TEntity> entities)
|
|
{
|
|
foreach (var entity in entities)
|
|
{
|
|
_dbSet.Attach(entity);
|
|
_context.Entry(entity).State = EntityState.Modified;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deletes an entity from the database.
|
|
/// </summary>
|
|
/// <param name="entity">The entity to delete.</param>
|
|
public void Delete(TEntity entity)
|
|
{
|
|
if (_context.Entry(entity).State == EntityState.Detached)
|
|
{
|
|
_dbSet.Attach(entity);
|
|
}
|
|
_dbSet.Remove(entity);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deletes multiple entities from the database.
|
|
/// </summary>
|
|
/// <param name="entities">The collection of entities to delete.</param>
|
|
public void DeleteRange(IEnumerable<TEntity> entities)
|
|
{
|
|
_dbSet.RemoveRange(entities);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves the first entity matching the specified condition or null if no match is found.
|
|
/// </summary>
|
|
/// <param name="predicate">An expression to filter entities.</param>
|
|
/// <returns>A task representing the asynchronous operation, with the matched entity as the result.</returns>
|
|
public async Task<TEntity?> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate)
|
|
{
|
|
return await _dbSet.FirstOrDefaultAsync(predicate);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines if any entities exist that match the specified condition.
|
|
/// </summary>
|
|
/// <param name="predicate">An expression to filter entities.</param>
|
|
/// <returns>A task representing the asynchronous operation, with a boolean result indicating existence.</returns>
|
|
public async Task<bool> AnyAsync(Expression<Func<TEntity, bool>> predicate)
|
|
{
|
|
return await _dbSet.AnyAsync(predicate);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves all pending changes to the database.
|
|
/// </summary>
|
|
/// <returns>A task representing the asynchronous operation.</returns>
|
|
public async Task SaveAsync()
|
|
{
|
|
await _context.SaveChangesAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Executes a raw SQL query and maps the result to the specified entity type.
|
|
/// </summary>
|
|
/// <param name="sql">The raw SQL query.</param>
|
|
/// <param name="parameters">Optional parameters for the query.</param>
|
|
/// <returns>An <see cref="IEnumerable{TEntity}"/> representing the result set.</returns>
|
|
public async Task<IEnumerable<TEntity>> ExecuteRawSqlAsync(string sql, params object[] parameters)
|
|
{
|
|
return await _dbSet.FromSqlRaw(sql, parameters).ToListAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Counts the total number of entities in the database.
|
|
/// </summary>
|
|
/// <returns>A task representing the asynchronous operation, with the count as the result.</returns>
|
|
public async Task<int> CountAsync()
|
|
{
|
|
return await _dbSet.CountAsync();
|
|
}
|
|
}
|
|
}
|