using AutoMapper; 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 IMapper Mapper { get; } public DbRepository(TDbContext context, Func> queryFactory, IMapper mapper) { Context = context; Entities = queryFactory(context); Mapper = mapper; } public virtual async Task CreateAsync(TEntity entity, CancellationToken cancel = default) { Entities.Add(entity); await Context.SaveChangesAsync(cancel); return entity; } public virtual async Task> CreateAsync(IEnumerable entities, CancellationToken cancel = default) { Entities.AddRange(entities); await Context.SaveChangesAsync(cancel); return entities; } public IQueryable Where(Expression> expression) => Entities.AsQueryable().Where(expression); public IQueryable Get() => Entities.AsNoTracking(); public virtual Task UpdateAsync(TDto dto, Expression> expression, CancellationToken cancel = default) => UpdateAsync(dto, q => q.Where(expression), cancel); public virtual async Task UpdateAsync(TDto dto, Func, IQueryable> query, CancellationToken cancel = default) { var entities = await query(Entities).ToListAsync(cancel); for (int i = entities.Count - 1; i >= 0; i--) { Mapper.Map(dto, entities[i]); Entities.Update(entities[i]); } await Context.SaveChangesAsync(cancel); } public virtual Task DeleteAsync(Expression> expression, CancellationToken cancel = default) => DeleteAsync(q => q.Where(expression), cancel); public virtual async Task DeleteAsync(Func, IQueryable> query, CancellationToken cancel = default) { var entities = await query(Entities).ToListAsync(cancel); for (int i = entities.Count - 1; i >= 0; i--) { Entities.Remove(entities[i]); } await Context.SaveChangesAsync(cancel); } #region Obsolete [Obsolete("Use IRepository.Where")] public IQueryable Read() => Entities.AsQueryable(); [Obsolete("Use IRepository.Get")] public IQueryable ReadOnly() => Entities.AsNoTracking(); #endregion } public class DbRepository : IRepository { private readonly IRepositoryFactory _factory; public DbRepository(IRepositoryFactory factory) { _factory = factory; } public IRepository Entity() where TEntity : IEntity => _factory.Get(); }