using System.Collections.Immutable; using System.Linq.Expressions; using Microsoft.EntityFrameworkCore; using WatchIt.Database; using WatchIt.DTO.Query; namespace WatchIt.WebAPI.Repositories; public abstract class Repository : IRepository where T : class { #region SERVICES protected readonly DatabaseContext Database; #endregion #region FIELDS protected readonly DbSet DefaultSet; #endregion #region CONSTRUCTORS protected Repository(DatabaseContext database) { Database = database; DefaultSet = database.Set(); } #endregion #region PUBLIC METHODS public async Task> GetAllAsync(Func, IQueryable>? additionalIncludes = null) => await GetAllAsync(additionalIncludes); public async Task UpdateAsync(T entity, Action updateFunc) => await UpdateAsync(entity, updateFunc); public async Task AddAsync(T entity) => await AddAsync(entity); public async Task UpdateOrAddAsync(T? entity, Func addFunc, Action updateFunc) => await UpdateOrAddAsync(entity, addFunc, updateFunc); public async Task DeleteAsync(T entity) => await DeleteAsync(entity); public async Task DeleteAsync(Expression> predicate) => await DeleteAsync(predicate); #endregion #region PRIVATE METHODS protected async Task> GetAllAsync(Func, IQueryable>? additionalIncludes = null) where TEntity : class => await Database.Set() .Include(additionalIncludes) .ToListAsync(); protected async Task UpdateAsync(TEntity entity, Action updateFunc) where TEntity : class { updateFunc(entity); Database.Set().Update(entity); await Database.SaveChangesAsync(); } protected async Task AddAsync(TEntity entity) where TEntity : class { await Database.Set().AddAsync(entity); await Database.SaveChangesAsync(); } protected async Task UpdateOrAddAsync(TEntity? entity, Func addFunc, Action updateFunc) where TEntity : class { if (entity is null) { entity = addFunc(); await Database.Set().AddAsync(entity); } else { updateFunc(entity); Database.Set().Update(entity); } await Database.SaveChangesAsync(); return entity; } protected async Task DeleteAsync(TEntity entity) where TEntity : class { DbSet dbSet = Database.Set(); dbSet.Attach(entity); dbSet.Remove(entity); await Database.SaveChangesAsync(); } protected async Task DeleteAsync(Expression> predicate) where TEntity : class { DbSet dbSet = Database.Set(); IQueryable entities = dbSet.Where(predicate); dbSet.AttachRange(entities); dbSet.RemoveRange(entities); await Database.SaveChangesAsync(); } #endregion }