using DigitalData.Core.Abstraction.Application.Repository; 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; public IEntityMapper Mapper { get; } public DbRepository(TDbContext context, Func> queryFactory, IEntityMapper 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 IReadQuery Read(params Expression>[] expressions) => new ReadQuery(Entities.AsNoTracking()).Where(expressions); public virtual async Task UpdateAsync(TDto dto, Expression> expression, CancellationToken ct = default) { var entities = await Entities.Where(expression).ToListAsync(ct); for (int i = entities.Count - 1; i >= 0; i--) { Mapper.Map(dto, entities[i]); Entities.Update(entities[i]); } await Context.SaveChangesAsync(ct); } public virtual async Task DeleteAsync(Expression> expression, CancellationToken ct = default) { var entities = await Entities.Where(expression).ToListAsync(ct); for (int i = entities.Count - 1; i >= 0; i--) { Entities.Remove(entities[i]); } await Context.SaveChangesAsync(ct); } #region Obsolete [Obsolete("Use Read-method returning IReadQuery instead.")] public virtual async Task> ReadAllAsync(Expression>? expression = null, CancellationToken ct = default) => expression is null ? await Entities.AsNoTracking().ToListAsync(ct) : await Entities.AsNoTracking().Where(expression).ToListAsync(ct); [Obsolete("Use Read-method returning IReadQuery instead.")] public virtual async Task ReadOrDefaultAsync(Expression> expression, bool single = true, CancellationToken ct = default) => single ? await Entities.AsNoTracking().Where(expression).SingleOrDefaultAsync(ct) : await Entities.AsNoTracking().Where(expression).FirstOrDefaultAsync(ct); [Obsolete("Use Read-method returning IReadQuery instead.")] public virtual async Task> ReadAllAsync(Expression>? expression = null, CancellationToken ct = default) => Mapper.Map(await ReadAllAsync(expression, ct)); [Obsolete("Use Read-method returning IReadQuery instead.")] public virtual async Task ReadOrDefaultAsync(Expression> expression, bool single = true, CancellationToken ct = default) { var entity = await ReadOrDefaultAsync(expression, single, ct); return entity is null ? default : Mapper.Map(entity); } #endregion }