87 lines
3.5 KiB
C#

using DigitalData.Core.Abstraction.Application.Repository;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;
namespace DigitalData.Core.Infrastructure;
public class DbRepository<TDbContext, TEntity> : IRepository<TEntity> where TDbContext : DbContext where TEntity : class
{
protected internal readonly TDbContext Context;
protected internal readonly DbSet<TEntity> Entities;
public IEntityMapper<TEntity> Mapper { get; }
public DbRepository(TDbContext context, Func<TDbContext, DbSet<TEntity>> queryFactory, IEntityMapper<TEntity> mapper)
{
Context = context;
Entities = queryFactory(context);
Mapper = mapper;
}
public virtual async Task<TEntity> CreateAsync(TEntity entity, CancellationToken ct = default)
{
Entities.Add(entity);
await Context.SaveChangesAsync(ct);
return entity;
}
public virtual async Task<IEnumerable<TEntity>> CreateAsync(IEnumerable<TEntity> entities, CancellationToken ct = default)
{
Entities.AddRange(entities);
await Context.SaveChangesAsync(ct);
return entities;
}
public IReadQuery<TEntity> Read(params Expression<Func<TEntity, bool>>[] expressions) => new ReadQuery<TEntity>(Entities.AsNoTracking()).Where(expressions);
public virtual async Task UpdateAsync<TDto>(TDto dto, Expression<Func<TEntity, bool>> 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<Func<TEntity, bool>> 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<TEntity> instead.")]
public virtual async Task<IEnumerable<TEntity>> ReadAllAsync(Expression<Func<TEntity, bool>>? 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<TEntity> instead.")]
public virtual async Task<TEntity?> ReadOrDefaultAsync(Expression<Func<TEntity, bool>> 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<TEntity> instead.")]
public virtual async Task<IEnumerable<TDto>> ReadAllAsync<TDto>(Expression<Func<TEntity, bool>>? expression = null, CancellationToken ct = default)
=> Mapper.Map<TDto>(await ReadAllAsync(expression, ct));
[Obsolete("Use Read-method returning IReadQuery<TEntity> instead.")]
public virtual async Task<TDto?> ReadOrDefaultAsync<TDto>(Expression<Func<TEntity, bool>> expression, bool single = true, CancellationToken ct = default)
{
var entity = await ReadOrDefaultAsync(expression, single, ct);
return entity is null ? default : Mapper.Map<TDto>(entity);
}
#endregion
}