Files
Core.BluePrint.Packages/Core.Blueprint.SQLServer/Repositories/EntityRepository.cs
Sergio Matias Urquin 83fc1878c4 Add project files.
2025-04-29 18:42:29 -06:00

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();
}
}
}