using Microsoft.EntityFrameworkCore; using Strata.SqlTools.Breakdowns.SqlServer; using Strata.SqlTools.EFCore.Abstractions; using Strata.SqlTools.EFCore.Models; namespace Strata.SqlTools.EFCore.Services; /// /// Interface for a generic repository pattern for QueryBreakdown entities. /// Provides a simplified API for common database operations. /// public interface IQueryBreakdownRepository { /// /// Adds a new QueryBreakdown to the repository and saves changes. /// /// The QueryBreakdown to add. /// The ID of the added entity. Task AddAsync(QueryBreakdown queryBreakdown); /// /// Retrieves a QueryBreakdown by ID and converts it from the entity. /// /// The ID of the QueryBreakdown entity. /// The QueryBreakdown, or null if not found. Task GetByIdAsync(int id); /// /// Retrieves a QueryBreakdownEntity by ID. /// /// The ID of the entity. /// The QueryBreakdownEntity, or null if not found. Task GetEntityByIdAsync(int id); /// /// Gets all QueryBreakdowns. /// /// A list of all QueryBreakdowns. Task> GetAllAsync(); /// /// Gets all QueryBreakdownEntities. /// /// A list of all QueryBreakdownEntities. Task> GetAllEntitiesAsync(); /// /// Updates an existing QueryBreakdown and saves changes. /// /// The ID of the entity to update. /// The updated QueryBreakdown. Task UpdateAsync(int id, QueryBreakdown queryBreakdown); /// /// Deletes a QueryBreakdown by ID and saves changes. /// /// The ID of the entity to delete. /// True if the entity was deleted; false if not found. Task DeleteAsync(int id); /// /// Gets the count of all QueryBreakdown entities. /// /// The count of entities. Task GetCountAsync(); } /// /// Implementation of IQueryBreakdownRepository for managing QueryBreakdown entities in Entity Framework Core. /// public class QueryBreakdownRepository : IQueryBreakdownRepository { private readonly DbContext _context; private readonly IQueryBreakdownMapper _mapper; /// /// Initializes a new instance of the QueryBreakdownRepository. /// /// The EF Core DbContext. /// The mapper for converting between QueryBreakdown and QueryBreakdownEntity. public QueryBreakdownRepository(DbContext context, IQueryBreakdownMapper mapper) { ArgumentNullException.ThrowIfNull(context); ArgumentNullException.ThrowIfNull(mapper); _context = context; _mapper = mapper; } /// /// Adds a new QueryBreakdown to the repository and saves changes. /// public async Task AddAsync(QueryBreakdown queryBreakdown) { ArgumentNullException.ThrowIfNull(queryBreakdown); var (entity, parameters, withClauses) = _mapper.MapToEntityWithRelations(queryBreakdown); // Add the main entity _context.Set().Add(entity); await _context.SaveChangesAsync(); // Add related entities with foreign key set foreach (var param in parameters) { param.QueryBreakdownEntityId = entity.Id; _context.Set().Add(param); } foreach (var withClause in withClauses) { withClause.QueryBreakdownEntityId = entity.Id; _context.Set().Add(withClause); } await _context.SaveChangesAsync(); return entity.Id; } /// /// Retrieves a QueryBreakdown by ID and converts it from the entity. /// public async Task GetByIdAsync(int id) { var entity = await _context.Set() .Include(e => e.Parameters) .Include(e => e.WithClauses) .FirstOrDefaultAsync(e => e.Id == id); return entity != null ? _mapper.MapToDomainModelWithRelations(entity) : null; } /// /// Retrieves a QueryBreakdownEntity by ID. /// public async Task GetEntityByIdAsync(int id) { return await _context.Set() .FirstOrDefaultAsync(e => e.Id == id); } /// /// Gets all QueryBreakdowns. /// public async Task> GetAllAsync() { var entities = await _context.Set().ToListAsync(); return entities.ConvertAll(e => _mapper.MapToDomainModel(e)); } /// /// Gets all QueryBreakdownEntities. /// public async Task> GetAllEntitiesAsync() { return await _context.Set().ToListAsync(); } /// /// Updates an existing QueryBreakdown and saves changes. /// public async Task UpdateAsync(int id, QueryBreakdown queryBreakdown) { ArgumentNullException.ThrowIfNull(queryBreakdown); var entity = await _context.Set().FirstOrDefaultAsync(e => e.Id == id); if (entity == null) { throw new InvalidOperationException($"QueryBreakdown with ID {id} not found."); } var updatedEntity = _mapper.MapToEntity(queryBreakdown); // Update the main entity entity.SelectClause = updatedEntity.SelectClause; entity.SelectClauseComment = updatedEntity.SelectClauseComment; entity.FromClause = updatedEntity.FromClause; entity.FromClauseComment = updatedEntity.FromClauseComment; entity.WhereClause = updatedEntity.WhereClause; entity.WhereClauseComment = updatedEntity.WhereClauseComment; entity.GroupByClause = updatedEntity.GroupByClause; entity.GroupByClauseComment = updatedEntity.GroupByClauseComment; entity.HavingClause = updatedEntity.HavingClause; entity.HavingClauseComment = updatedEntity.HavingClauseComment; entity.OrderByClause = updatedEntity.OrderByClause; entity.OrderByClauseComment = updatedEntity.OrderByClauseComment; entity.WithClause = updatedEntity.WithClause; entity.RawSql = updatedEntity.RawSql; entity.SetupClausesJson = updatedEntity.SetupClausesJson; entity.FinishClausesJson = updatedEntity.FinishClausesJson; entity.ParametersJson = updatedEntity.ParametersJson; entity.UpdatedAt = DateTime.UtcNow; // Delete and recreate related entities var existingParameters = _context.Set().Where(p => p.QueryBreakdownEntityId == id); _context.Set().RemoveRange(existingParameters); var existingWithClauses = _context.Set().Where(w => w.QueryBreakdownEntityId == id); _context.Set().RemoveRange(existingWithClauses); var (_, parameters, withClauses) = _mapper.MapToEntityWithRelations(queryBreakdown); foreach (var param in parameters) { param.QueryBreakdownEntityId = id; _context.Set().Add(param); } foreach (var withClause in withClauses) { withClause.QueryBreakdownEntityId = id; _context.Set().Add(withClause); } await _context.SaveChangesAsync(); } /// /// Deletes a QueryBreakdown by ID and saves changes. /// public async Task DeleteAsync(int id) { var entity = await _context.Set().FirstOrDefaultAsync(e => e.Id == id); if (entity == null) { return false; } _context.Set().Remove(entity); await _context.SaveChangesAsync(); return true; } /// /// Gets the count of all QueryBreakdown entities. /// public async Task GetCountAsync() { return await _context.Set().CountAsync(); } }