using System.Linq.Expressions; using Infrastructure.Base; using Microsoft.EntityFrameworkCore; using Shared; using System.Linq.Dynamic.Core; namespace Infrastructure.Repositories; public class GenericRepository : IRepository where T : EntityBase { protected readonly OptifitDbContext context; public GenericRepository(OptifitDbContext context) { this.context = context; } public IEnumerable GetAll(params Expression>[] includes) { IQueryable query = this.context.Set(); query = includes.Aggregate(query, (current, include) => current.Include(include)); return query.ToList(); } public async Task> GetAllAsync(Expression>? expression = null, CancellationToken cancellationToken = default, params Expression>[] includes) { IQueryable query = this.context.Set(); query = includes.Aggregate(query, (current, include) => current.Include(include)); if (expression != null) query = query.Where(expression); return await query.ToDynamicListAsync(cancellationToken: cancellationToken); } public virtual async Task GetByIdAsync(object id, params Expression>[] includes) { IQueryable query = this.context.Set(); query = query.Where(entity => entity.Id.Equals(id)); query = includes.Aggregate(query, (current, include) => current.Include(include)); return await query.FirstOrDefaultAsync(); } public async Task InsertAsync(T obj) { _ = await this.context.Set() .AddAsync(obj); } public void Update(T obj) { _ = this.context.Set().Attach(obj); this.context.Entry(obj).State = EntityState.Modified; } public void Delete(object id) { var existing = this.context .Set() .Find(id); _ = this.context.Set().Remove(existing!); } public async Task> GetPaginatedListAsync( int pageNumber, int pageSize, string[]? orderBy = null, Expression>? expression = null, CancellationToken cancellationToken = default, params Expression>[] includes) { IQueryable query = this.context.Set(); query = includes.Aggregate(query, (current, include) => current.Include(include)); if (expression != null) query = query.Where(expression); var ordering = orderBy?.Any() == true ? string.Join(",", orderBy) : null; query = !string.IsNullOrWhiteSpace(ordering) ? query.OrderBy(ordering) : query.OrderBy(a => a.Id); var count = await query .AsNoTracking() .CountAsync(cancellationToken: cancellationToken); var items = await query .Skip(pageNumber * pageSize) .Take(pageSize) .ToDynamicListAsync(cancellationToken: cancellationToken); return new PaginatedResult(items, count, pageNumber, pageSize); } public async Task CountAsync(Expression>? expression = null, CancellationToken cancellationToken = default) { IQueryable query = this.context.Set(); if (expression != null) query = query.Where(expression); return await query .AsNoTracking() .CountAsync(cancellationToken: cancellationToken); } public async Task ExistsAsync(Expression> expression, CancellationToken cancellationToken = default) { return await this.context.Set().AnyAsync(expression, cancellationToken: cancellationToken); } }