feat: Implement QueryExecutor for executing queries using IQueryable

- Added a record `QueryExecutor<TEntity>` implementing `IQueryExecutor<TEntity>` for executing common query operations like First, Single, and ToList both synchronously and asynchronously.
- Methods leverage the IQueryable interface to perform database queries for entity types.
This commit is contained in:
Developer 02 2025-04-29 16:56:13 +02:00
parent 5331efe3c1
commit 6e82b24578
2 changed files with 104 additions and 0 deletions

View File

@ -0,0 +1,70 @@
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
/// <summary>
/// Provides methods for executing common Entity Framework queries on a given entity type.
/// This interface abstracts away the direct usage of Entity Framework methods for querying data
/// and provides asynchronous and synchronous operations for querying a collection or single entity.
/// </summary>
/// <typeparam name="TEntity">The type of the entity being queried.</typeparam>
public interface IQueryExecutor<TEntity>
{
/// <summary>
/// Asynchronously retrieves the first entity or a default value if no entity is found.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the entity or a default value.</returns>
public Task<TEntity?> FirstOrDefaultAsync();
/// <summary>
/// Asynchronously retrieves a single entity or a default value if no entity is found.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the entity or a default value.</returns>
public Task<TEntity?> SingleOrDefaultAsync();
/// <summary>
/// Asynchronously retrieves a list of entities.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the list of entities.</returns>
public Task<IEnumerable<TEntity>> ToListAsync();
/// <summary>
/// Asynchronously retrieves the first entity. Throws an exception if no entity is found.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the first entity.</returns>
public Task<TEntity> FirstAsync();
/// <summary>
/// Asynchronously retrieves a single entity. Throws an exception if no entity is found.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the single entity.</returns>
public Task<TEntity> SingleAsync();
/// <summary>
/// Synchronously retrieves the first entity or a default value if no entity is found.
/// </summary>
/// <returns>The first entity or a default value.</returns>
public TEntity? FirstOrDefault();
/// <summary>
/// Synchronously retrieves a single entity or a default value if no entity is found.
/// </summary>
/// <returns>The single entity or a default value.</returns>
public TEntity? SingleOrDefault();
/// <summary>
/// Synchronously retrieves a list of entities.
/// </summary>
/// <returns>The list of entities.</returns>
public IEnumerable<TEntity> ToList();
/// <summary>
/// Synchronously retrieves the first entity. Throws an exception if no entity is found.
/// </summary>
/// <returns>The first entity.</returns>
public TEntity First();
/// <summary>
/// Synchronously retrieves a single entity. Throws an exception if no entity is found.
/// </summary>
/// <returns>The single entity.</returns>
public TEntity Single();
}

View File

@ -0,0 +1,34 @@
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
using Microsoft.EntityFrameworkCore;
namespace EnvelopeGenerator.Infrastructure;
public record QueryExecutor<TEntity>(IQueryable<TEntity> Queryable) : IQueryExecutor<TEntity>
{
public TEntity First() => Queryable.First();
public Task<TEntity> FirstAsync() => Queryable.FirstAsync();
public TEntity? FirstOrDefault() => Queryable.FirstOrDefault();
public Task<TEntity?> FirstOrDefaultAsync() => Queryable.FirstOrDefaultAsync();
public TEntity Single() => Queryable.Single();
public Task<TEntity> SingleAsync() => Queryable.SingleAsync();
public TEntity? SingleOrDefault() => Queryable.SingleOrDefault();
public Task<TEntity?> SingleOrDefaultAsync() => Queryable.SingleOrDefaultAsync();
public IEnumerable<TEntity> ToList() => Queryable.ToList();
public async Task<IEnumerable<TEntity>> ToListAsync() => await Queryable.ToListAsync();
}