DbRepository<TDbContext> now implements the IRepository interface, ensuring it conforms to the expected repository contract and interface requirements. This change improves consistency and enforces interface adherence across repository implementations.
162 lines
5.9 KiB
C#
162 lines
5.9 KiB
C#
using AutoMapper;
|
|
using DigitalData.Core.Abstraction.Application.Repository;
|
|
using DigitalData.Core.Infrastructure.Factory;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using System.Linq.Expressions;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
#if NETFRAMEWORK
|
|
using System.Collections.Generic;
|
|
using System;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
#endif
|
|
|
|
namespace DigitalData.Core.Infrastructure
|
|
{
|
|
public class DbRepository<TDbContext> : IRepository where TDbContext : DbContext
|
|
{
|
|
protected internal readonly TDbContext Context;
|
|
|
|
public DbRepository(TDbContext context)
|
|
{
|
|
Context = context;
|
|
}
|
|
|
|
public Task<int> ExecuteQueryRawAsync([NotParameterized] string sql, IEnumerable<object> parameters, CancellationToken cancel = default)
|
|
{
|
|
return Context.Database.ExecuteSqlRawAsync(sql, parameters, cancel);
|
|
}
|
|
|
|
public Task<int> ExecuteQueryInterpolatedAsync(FormattableString sql, CancellationToken cancel = default)
|
|
{
|
|
return Context.Database.ExecuteSqlInterpolatedAsync(sql, cancel);
|
|
}
|
|
|
|
public int ExecuteQueryRaw([NotParameterized] string sql, params object[] parameters)
|
|
{
|
|
return Context.Database.ExecuteSqlRaw(sql, parameters);
|
|
}
|
|
|
|
public int ExecuteQueryInterpolated(FormattableString sql)
|
|
{
|
|
return Context.Database.ExecuteSqlInterpolated(sql);
|
|
}
|
|
}
|
|
|
|
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 IMapper
|
|
#if NET
|
|
?
|
|
#endif
|
|
Mapper { get; }
|
|
|
|
public DbRepository(TDbContext context, DbSetFactory<TDbContext, TEntity> factory, IMapper
|
|
#if NET
|
|
?
|
|
#endif
|
|
mapper = null)
|
|
{
|
|
Context = context;
|
|
Entities = factory.Create(context);
|
|
Mapper = mapper;
|
|
}
|
|
|
|
#region Create
|
|
public virtual async Task<TEntity> CreateAsync(TEntity entity, CancellationToken cancel = default)
|
|
{
|
|
Entities.Add(entity);
|
|
await Context.SaveChangesAsync(cancel);
|
|
return entity;
|
|
}
|
|
|
|
public virtual async Task<IEnumerable<TEntity>> CreateAsync(IEnumerable<TEntity> entities, CancellationToken cancel = default)
|
|
{
|
|
Entities.AddRange(entities);
|
|
await Context.SaveChangesAsync(cancel);
|
|
return entities;
|
|
}
|
|
|
|
public virtual Task<TEntity> CreateAsync<TDto>(TDto dto, CancellationToken cancel = default)
|
|
=> CreateAsync(Mapper
|
|
#if NET
|
|
!
|
|
#endif
|
|
.Map<TEntity>(dto), cancel);
|
|
|
|
public virtual Task<IEnumerable<TEntity>> CreateAsync<TDto>(IEnumerable<TDto> dtos, CancellationToken cancel = default)
|
|
=> CreateAsync(Mapper
|
|
#if NET
|
|
!
|
|
#endif
|
|
.Map<IEnumerable<TEntity>>(dtos), cancel);
|
|
#endregion Create
|
|
|
|
#region Read
|
|
public virtual IQueryable<TEntity> Query => Entities.AsNoTracking();
|
|
|
|
public IQueryable<TEntity> QueryRaw([NotParameterized] string sql, params object[] parameters) => Entities.FromSqlRaw(sql, parameters);
|
|
|
|
public IQueryable<TEntity> QueryInterpolated([NotParameterized] FormattableString sql) => Entities.FromSqlInterpolated(sql);
|
|
|
|
public virtual IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> expression) => Entities.AsNoTracking().Where(expression);
|
|
|
|
public virtual IEnumerable<TEntity> GetAll() => Entities.AsNoTracking().ToList();
|
|
|
|
public virtual async Task<IEnumerable<TEntity>> GetAllAsync(CancellationToken cancel = default) => await Entities.AsNoTracking().ToListAsync(cancel);
|
|
#endregion Read
|
|
|
|
#region Update
|
|
public virtual Task UpdateAsync<TDto>(TDto dto, Expression<Func<TEntity, bool>> expression, CancellationToken cancel = default) => UpdateAsync(dto, q => q.Where(expression), cancel);
|
|
|
|
public virtual Task UpdateAsync<TDto>(TDto dto, Func<IQueryable<TEntity>, IQueryable<TEntity>> query, CancellationToken cancel = default)
|
|
=> UpdateAsync(entity => Mapper
|
|
#if NET
|
|
!
|
|
#endif
|
|
.Map(dto, entity), query, cancel);
|
|
|
|
public virtual async Task UpdateAsync(Action<TEntity> modification, Func<IQueryable<TEntity>, IQueryable<TEntity>> 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<TEntity> modification, Expression<Func<TEntity, bool>> expression, CancellationToken cancel = default)
|
|
=> UpdateAsync(modification, q => q.Where(expression), cancel);
|
|
#endregion Update
|
|
|
|
#region Delete
|
|
public virtual Task DeleteAsync(Expression<Func<TEntity, bool>> expression, CancellationToken cancel = default) => DeleteAsync(q => q.Where(expression), cancel);
|
|
|
|
public virtual async Task DeleteAsync(Func<IQueryable<TEntity>, IQueryable<TEntity>> 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<TEntity>.Where")]
|
|
public virtual IQueryable<TEntity> Read() => Entities.AsQueryable();
|
|
|
|
[Obsolete("Use IRepository<TEntity>.Get")]
|
|
public virtual IQueryable<TEntity> ReadOnly() => Entities.AsNoTracking();
|
|
#endregion
|
|
}
|
|
} |