using AutoMapper; using DigitalData.Core.Abstractions.Infrastructure; using Microsoft.EntityFrameworkCore; using System.Linq.Expressions; namespace DigitalData.Core.Infrastructure; public class DbRepository : IRepository where TDbContext : DbContext where TEntity : class { protected internal readonly TDbContext Context; protected internal readonly DbSet Entities; protected internal readonly IMapper Mapper; public DbRepository(TDbContext context, Func> queryFactory, IMapper mapper) { Context = context; Entities = queryFactory(context); Mapper = mapper; } public virtual async Task CreateAsync(TEntity entity, CancellationToken ct = default) { Entities.Add(entity); await Context.SaveChangesAsync(ct); return entity; } public virtual async Task> CreateAsync(IEnumerable entities, CancellationToken ct = default) { Entities.AddRange(entities); await Context.SaveChangesAsync(ct); return entities; } public virtual async Task> ReadAsync(Expression>? expression = null, CancellationToken ct = default) => expression is null ? await Entities.AsNoTracking().ToListAsync(ct) : await Entities.AsNoTracking().Where(expression).ToListAsync(ct); public virtual async Task UpdateAsync(TUpdate update, Expression> expression, CancellationToken ct = default) { var entities = await Entities.Where(expression).ToListAsync(ct); foreach (var entity in entities) { Mapper.Map(update, entity); Entities.Add(entity); } await Context.SaveChangesAsync(ct); } public virtual async Task DeleteAsync(Expression> expression, CancellationToken ct = default) { var entities = await Entities.Where(expression).ToListAsync(ct); foreach (var entity in entities) { entities.Remove(entity); } await Context.SaveChangesAsync(ct); } }