using AutoMapper; using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.Core.Abstractions.Interfaces; using DigitalData.Core.Infrastructure.Factory; using Microsoft.EntityFrameworkCore; using System.Linq.Expressions; using Microsoft.Extensions.DependencyInjection; #if NETFRAMEWORK using System.Collections.Generic; using System; using System.Linq; using System.Threading; using System.Threading.Tasks; #endif namespace DigitalData.Core.Infrastructure #if NET ; #elif NETFRAMEWORK { #endif public class DbRepository : IRepository where TDbContext : DbContext where TEntity : class { protected internal readonly TDbContext Context; protected internal readonly DbSet Entities; public IMapper #if NET ? #endif Mapper { get; } public DbRepository(TDbContext context, DbSetFactory factory, IMapper #if NET ? #endif mapper = null) { Context = context; Entities = factory.Create(context); Mapper = mapper; } #region Create 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 virtual Task CreateAsync(TDto dto, CancellationToken cancel = default) => CreateAsync(Mapper #if NET ! #endif .Map(dto), cancel); public virtual Task> CreateAsync(IEnumerable dtos, CancellationToken cancel = default) => CreateAsync(Mapper #if NET ! #endif .Map>(dtos), cancel); #endregion Create #region Read public virtual IQueryable Query => Entities.AsNoTracking(); public virtual IQueryable Where(Expression> expression) => Entities.AsNoTracking().Where(expression); public virtual IEnumerable GetAll() => Entities.AsNoTracking().ToList(); public virtual async Task> GetAllAsync(CancellationToken cancel = default) => await Entities.AsNoTracking().ToListAsync(cancel); #endregion Read #region Update public virtual Task UpdateAsync(TDto dto, Expression> expression, CancellationToken cancel = default) => UpdateAsync(dto, q => q.Where(expression), cancel); public virtual Task UpdateAsync(TDto dto, Func, IQueryable> query, CancellationToken cancel = default) => UpdateAsync(entity => Mapper #if NET ! #endif .Map(dto, entity), query, cancel); public virtual async Task UpdateAsync(Action modification, Func, IQueryable> query, CancellationToken cancel = default) { var entities = await query(Entities).ToListAsync(cancel); for (int i = entities.Count - 1; i >= 0; i--) modification.Invoke(entities[i]); await Context.SaveChangesAsync(cancel); } public virtual Task UpdateAsync(Action modification, Expression> expression, CancellationToken cancel = default) => UpdateAsync(modification, q => q.Where(expression), cancel); #endregion Update #region Delete 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); } #endregion Delete #region Obsolete [Obsolete("Use IRepository.Where")] public virtual IQueryable Read() => Entities.AsQueryable(); [Obsolete("Use IRepository.Get")] public virtual IQueryable ReadOnly() => Entities.AsNoTracking(); #endregion } #if NETFRAMEWORK } #endif