using System.Linq.Expressions; using LctMonolith.Database.Data; using Microsoft.EntityFrameworkCore; namespace LctMonolith.Database.Repositories; /// /// Generic repository implementation for common CRUD and query composition. /// public class GenericRepository : IGenericRepository where TEntity : class { protected readonly AppDbContext Context; protected readonly DbSet Set; public GenericRepository(AppDbContext context) { Context = context; Set = context.Set(); } public IQueryable Query( Expression>? filter = null, Func, IOrderedQueryable>? orderBy = null, params Expression>[] includes) { IQueryable query = Set; if (filter != null) query = query.Where(filter); if (includes != null) { foreach (var include in includes) query = query.Include(include); } if (orderBy != null) query = orderBy(query); return query; } public async Task GetByIdAsync(object id) => await Set.FindAsync(id) ?? null; public ValueTask FindAsync(params object[] keyValues) => Set.FindAsync(keyValues); public async Task AddAsync(TEntity entity, CancellationToken ct = default) => await Set.AddAsync(entity, ct); public async Task AddRangeAsync(IEnumerable entities, CancellationToken ct = default) => await Set.AddRangeAsync(entities, ct); public void Update(TEntity entity) => Set.Update(entity); public void Remove(TEntity entity) => Set.Remove(entity); public async Task RemoveByIdAsync(object id, CancellationToken ct = default) { var entity = await Set.FindAsync([id], ct); if (entity == null) throw new KeyNotFoundException($"Entity {typeof(TEntity).Name} id={id} not found"); Set.Remove(entity); } }