Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #69

Merged
merged 2 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
337 changes: 158 additions & 179 deletions Source/Euonia.Repository.EfCore/EfCoreRepository.cs
Original file line number Diff line number Diff line change
@@ -1,190 +1,169 @@
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Nerosoft.Euonia.Collections;
using Nerosoft.Euonia.Domain;
using Nerosoft.Euonia.Linq;

namespace Nerosoft.Euonia.Repository.EfCore;

/// <inheritdoc />
public class EfCoreRepository<TContext, TEntity, TKey> : Repository<TContext, TEntity, TKey>
where TKey : IEquatable<TKey>
where TEntity : class, IEntity<TKey>
where TContext : DbContext, IRepositoryContext
where TKey : IEquatable<TKey>
where TEntity : class, IEntity<TKey>
where TContext : DbContext, IRepositoryContext
{
/// <summary>
/// Initializes a new instance of the <see cref="EfCoreRepository{TContext, TEntity, TKey}"/> class.
/// </summary>
/// <param name="provider">The repository context.</param>
public EfCoreRepository(IContextProvider provider)
: base(provider)
{
}

/// <inheritdoc />
protected override void Dispose(bool disposing)
{
//Context?.Dispose();
}

/// <inheritdoc />
public override IQueryable<TEntity> Queryable()
{
var query = Context.Set<TEntity>().AsQueryable();
if (Actions.Count > 0)
{
query = Actions.Aggregate(query, (current, action) => action(current));
}

return query;
}

/// <inheritdoc />
public override async Task<TEntity> GetAsync(TKey key, CancellationToken cancellationToken = default)
{
return await Context.FindAsync<TEntity>(key);
}

/// <inheritdoc />
public override async Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
{
return await Context.Set<TEntity>().FirstOrDefaultAsync(predicate, cancellationToken);
}

/// <inheritdoc />
public override IQueryable<TEntity> Fetch(Expression<Func<TEntity, bool>> predicate)
{
return Queryable().Where(predicate);
}

/// <inheritdoc />
public override IQueryable<TEntity> Fetch(Expression<Func<TEntity, bool>> predicate, Action<Orderable<TEntity>> order)
{
var orderable = new Orderable<TEntity>(Fetch(predicate));
order(orderable);
return orderable.Queryable;
}

/// <inheritdoc />
public override IQueryable<TEntity> Fetch(Expression<Func<TEntity, bool>> predicate, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> order)
{
var query = Queryable().Where(predicate);
query = order(query);

return query;
}

/// <inheritdoc />
public override async Task<PageableCollection<TEntity>> FetchAsync(Expression<Func<TEntity, bool>> predicate, Action<Orderable<TEntity>> order, int? page, int? size, CancellationToken cancellationToken = default)
{
var pageIndex = page ?? 1;
var pageSize = size ?? int.MaxValue;

var handler = new QueryHandler<TEntity>(Queryable());

handler.AddCriteria(predicate);
var count = handler.GetCount();

handler.SetPage(pageIndex).SetSize(pageSize);

handler.SetCollator(order);

var list = await handler.QueryAsync(async query => await query.ToListAsync(cancellationToken));

return new PageableCollection<TEntity>(list) { TotalCount = count, PageNumber = pageIndex, PageSize = pageSize };
}

/// <inheritdoc />
public override async Task<PageableCollection<TEntity>> FetchAsync(Expression<Func<TEntity, bool>> predicate, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> order, int? page, int? size, CancellationToken cancellationToken = default)
{
var pageIndex = page ?? 1;
var pageSize = size ?? int.MaxValue;

var handler = new QueryHandler<TEntity>(Queryable());

handler.AddCriteria(predicate);
var count = await handler.GetCountAsync(async query => await query.CountAsync(cancellationToken));

handler.SetPage(pageIndex).SetSize(pageSize);

handler.SetCollator(order);

var list = await handler.QueryAsync(async query => await query.ToListAsync(cancellationToken));

return new PageableCollection<TEntity>(list) { TotalCount = count, PageNumber = pageIndex, PageSize = pageSize };
}

/// <inheritdoc />
public override async Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
{
return await Context.Set<TEntity>().CountAsync(predicate, cancellationToken);
}

/// <inheritdoc />
public override async Task<long> LongCountAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
{
return await Context.Set<TEntity>().LongCountAsync(predicate, cancellationToken);
}

/// <inheritdoc />
public override async Task<TEntity> InsertAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default)
{
var entry = await Context.AddAsync(entity, cancellationToken);
if (autoSave)
{
await SaveChangesAsync(cancellationToken);
}

return entry.Entity;
}

/// <inheritdoc />
public override async Task InsertAsync(IEnumerable<TEntity> entities, bool autoSave = true, CancellationToken cancellationToken = default)
{
await Context.AddRangeAsync(entities, cancellationToken);
if (autoSave)
{
await SaveChangesAsync(cancellationToken);
}
}

/// <inheritdoc />
public override async Task UpdateAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default)
{
var _ = Context.Update(entity);
if (autoSave)
{
await SaveChangesAsync(cancellationToken);
}
}

/// <inheritdoc />
public override async Task UpdateAsync(IEnumerable<TEntity> entities, bool autoSave = true, CancellationToken cancellationToken = default)
{
Context.UpdateRange(entities);
if (autoSave)
{
await SaveChangesAsync(cancellationToken);
}
}

/// <inheritdoc />
public override async Task DeleteAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default)
{
var _ = Context.Remove(entity);
if (autoSave)
{
await SaveChangesAsync(cancellationToken);
}
}

/// <inheritdoc />
public override async Task DeleteAsync(IEnumerable<TEntity> entities, bool autoSave = true, CancellationToken cancellationToken = default)
{
Context.RemoveRange(entities);
if (autoSave)
{
await SaveChangesAsync(cancellationToken);
}
}
/// <summary>
/// Initializes a new instance of the <see cref="EfCoreRepository{TContext, TEntity, TKey}"/> class.
/// </summary>
/// <param name="provider">The repository context.</param>
public EfCoreRepository(IContextProvider provider)
: base(provider)
{
}

/// <inheritdoc />
protected override void Dispose(bool disposing)
{
//Context?.Dispose();
}

/// <inheritdoc />
public override IQueryable<TEntity> Queryable()
{
var query = Context.Set<TEntity>().AsQueryable();
if (Actions.Count > 0)
{
query = Actions.Aggregate(query, (current, action) => action(current));
}

return query;
}

/// <inheritdoc />
public override IQueryable<TEntity> BuildQuery(Expression<Func<TEntity, bool>> predicate, Func<IQueryable<TEntity>, IQueryable<TEntity>> handle)
{
ArgumentNullException.ThrowIfNull(predicate);
var query = Context.Set<TEntity>().AsQueryable();
if (handle != null)
{
query = handle(query);
}
return query.Where(predicate);
}

/// <inheritdoc />
public override async Task<TEntity> GetAsync(TKey key, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(key);
return await Context.FindAsync<TEntity>(key);
}

/// <inheritdoc />
public override Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate, Func<IQueryable<TEntity>, IQueryable<TEntity>> handle, CancellationToken cancellationToken = default)
{
return BuildQuery(predicate, handle).FirstOrDefaultAsync(predicate, cancellationToken);
}

/// <inheritdoc />
public override Task<List<TEntity>> FindAsync(Expression<Func<TEntity, bool>> predicate, Func<IQueryable<TEntity>, IQueryable<TEntity>> handle, CancellationToken cancellationToken = default)
{
return BuildQuery(predicate, handle).ToListAsync(cancellationToken);
}

/// <inheritdoc />
public override Task<List<TEntity>> FindAsync(Expression<Func<TEntity, bool>> predicate, Func<IQueryable<TEntity>, IQueryable<TEntity>> handle, int offset, int count, CancellationToken cancellationToken = default)
{
return BuildQuery(predicate, handle).Skip(offset).Take(count).ToListAsync(cancellationToken);
}

/// <inheritdoc />
public override Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate, Func<IQueryable<TEntity>, IQueryable<TEntity>> handle, CancellationToken cancellationToken = default)
{
return BuildQuery(predicate, handle).CountAsync(predicate, cancellationToken);
}

/// <inheritdoc />
public override Task<long> LongCountAsync(Expression<Func<TEntity, bool>> predicate, Func<IQueryable<TEntity>, IQueryable<TEntity>> handle, CancellationToken cancellationToken = default)
{
return BuildQuery(predicate, handle).LongCountAsync(predicate, cancellationToken);
}

/// <inheritdoc />
public override Task<bool> AnyAsync(Expression<Func<TEntity, bool>> predicate, Func<IQueryable<TEntity>, IQueryable<TEntity>> handle, CancellationToken cancellationToken = default)
{
return BuildQuery(predicate, handle).AnyAsync(predicate, cancellationToken);
}

/// <inheritdoc />
public override Task<bool> AllAsync(Expression<Func<TEntity, bool>> predicate, Func<IQueryable<TEntity>, IQueryable<TEntity>> handle, CancellationToken cancellationToken = default)
{
return BuildQuery(predicate, handle).AllAsync(predicate, cancellationToken);
}

/// <inheritdoc />
public override async Task<TEntity> InsertAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(entity);
var entry = await Context.AddAsync(entity, cancellationToken);
if (autoSave)
{
await SaveChangesAsync(cancellationToken);
}

return entry.Entity;
}

/// <inheritdoc />
public override async Task InsertAsync(IEnumerable<TEntity> entities, bool autoSave = true, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(entities);
await Context.AddRangeAsync(entities, cancellationToken);
if (autoSave)
{
await SaveChangesAsync(cancellationToken);
}
}

/// <inheritdoc />
public override async Task UpdateAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(entity);
var _ = Context.Update(entity);
if (autoSave)
{
await SaveChangesAsync(cancellationToken);
}
}

/// <inheritdoc />
public override async Task UpdateAsync(IEnumerable<TEntity> entities, bool autoSave = true, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(entities);
Context.UpdateRange(entities);
if (autoSave)
{
await SaveChangesAsync(cancellationToken);
}
}

/// <inheritdoc />
public override async Task DeleteAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(entity);
var _ = Context.Remove(entity);
if (autoSave)
{
await SaveChangesAsync(cancellationToken);
}
}

/// <inheritdoc />
public override async Task DeleteAsync(IEnumerable<TEntity> entities, bool autoSave = true, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(entities);
Context.RemoveRange(entities);
if (autoSave)
{
await SaveChangesAsync(cancellationToken);
}
}
}
Loading