#if NET48 using System.Data.Entity; #else using Microsoft.EntityFrameworkCore; #endif using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; using AutoMapper; using ECMJobRunner.Domain.Interfaces; using ECMJobRunner.Infrastructure.Data; namespace ECMJobRunner.Infrastructure.Repositories { /// /// Generic repository implementation for Entity Framework /// Uses AutoMapper for DTO mapping /// /// Entity type /// /// Constructor /// public class Repository(JobRunnerDbContext context, IMapper mapper) : IRepository where TEntity : class { /// /// Database context /// protected readonly JobRunnerDbContext Context = context ?? throw new ArgumentNullException(nameof(context)); /// /// DbSet for the entity /// protected readonly DbSet DbSet = context.Set(); /// /// AutoMapper instance for DTO mapping /// protected readonly IMapper Mapper = mapper ?? throw new ArgumentNullException(nameof(mapper)); /// public virtual async Task GetByIdAsync(long id, CancellationToken cancellationToken = default) { #if NET48 return await DbSet.FindAsync(cancellationToken, id); #else return await DbSet.FindAsync([id], cancellationToken); #endif } /// public virtual async Task> GetAllAsync(CancellationToken cancellationToken = default) { return await DbSet.ToListAsync(cancellationToken); } /// public virtual async Task> FindAsync(Expression> predicate, CancellationToken cancellationToken = default) { return await DbSet.Where(predicate).ToListAsync(cancellationToken); } /// public virtual async Task SingleOrDefaultAsync(Expression> predicate, CancellationToken cancellationToken = default) { return await DbSet.SingleOrDefaultAsync(predicate, cancellationToken); } /// public virtual async Task AddAsync(TDto dto, CancellationToken cancellationToken = default) where TDto : class { #if NETFRAMEWORK if (dto == null) throw new ArgumentNullException(nameof(dto)); #endif var entity = Mapper.Map(dto); #if NET48 DbSet.Add(entity); #else await DbSet.AddAsync(entity, cancellationToken); #endif await Context.SaveChangesAsync(cancellationToken); return entity; } /// public virtual async Task AddRangeAsync(IEnumerable dtos, CancellationToken cancellationToken = default) where TDto : class { #if NETFRAMEWORK if (dtos == null) throw new ArgumentNullException(nameof(dtos)); #endif var dtoList = dtos.ToList(); if (dtoList.Count == 0) return 0; var entities = Mapper.Map>(dtoList); #if NET48 DbSet.AddRange(entities); #else await DbSet.AddRangeAsync(entities, cancellationToken); #endif return await Context.SaveChangesAsync(cancellationToken); } /// public virtual async Task UpdateAsync(Expression> predicate, TDto dto, CancellationToken cancellationToken = default) where TDto : class { #if NETFRAMEWORK if (dto == null) throw new ArgumentNullException(nameof(dto)); #endif var entities = await DbSet.Where(predicate).ToListAsync(cancellationToken); if (entities.Count == 0) return 0; foreach (var entity in entities) { Mapper.Map(dto, entity); } return await Context.SaveChangesAsync(cancellationToken); } /// public virtual async Task UpdateSingleAsync(Expression> predicate, TDto dto, CancellationToken cancellationToken = default) where TDto : class { #if NETFRAMEWORK if (dto == null) throw new ArgumentNullException(nameof(dto)); #endif var entity = await SingleOrDefaultAsync(predicate, cancellationToken); if (entity == null) return false; Mapper.Map(dto, entity); await Context.SaveChangesAsync(cancellationToken); return true; } /// public virtual async Task DeleteAsync(Expression> predicate, CancellationToken cancellationToken = default) { var entities = await DbSet.Where(predicate).ToListAsync(cancellationToken); if (entities.Count == 0) return 0; DbSet.RemoveRange(entities); return await Context.SaveChangesAsync(cancellationToken); } /// public virtual async Task DeleteSingleAsync(Expression> predicate, CancellationToken cancellationToken = default) { var entity = await SingleOrDefaultAsync(predicate, cancellationToken); if (entity == null) return false; DbSet.Remove(entity); await Context.SaveChangesAsync(cancellationToken); return true; } } }