From 023e1589a3e26de20bfd8f41ccdf72471363e41f Mon Sep 17 00:00:00 2001 From: damon Date: Wed, 17 Jan 2024 22:11:00 +0800 Subject: [PATCH 1/2] Refactoring repository. --- .../EfCoreRepository.cs | 337 +++++++------ .../MongoRepository.cs | 296 ++++++------ .../Abstracts/IRepository.cs | 443 +++++++++++------- Source/Euonia.Repository/Core/Repository.cs | 124 ++--- 4 files changed, 640 insertions(+), 560 deletions(-) diff --git a/Source/Euonia.Repository.EfCore/EfCoreRepository.cs b/Source/Euonia.Repository.EfCore/EfCoreRepository.cs index 100cbc9..362c905 100644 --- a/Source/Euonia.Repository.EfCore/EfCoreRepository.cs +++ b/Source/Euonia.Repository.EfCore/EfCoreRepository.cs @@ -1,6 +1,5 @@ using System.Linq.Expressions; using Microsoft.EntityFrameworkCore; -using Nerosoft.Euonia.Collections; using Nerosoft.Euonia.Domain; using Nerosoft.Euonia.Linq; @@ -8,183 +7,163 @@ namespace Nerosoft.Euonia.Repository.EfCore; /// public class EfCoreRepository : Repository - where TKey : IEquatable - where TEntity : class, IEntity - where TContext : DbContext, IRepositoryContext + where TKey : IEquatable + where TEntity : class, IEntity + where TContext : DbContext, IRepositoryContext { - /// - /// Initializes a new instance of the class. - /// - /// The repository context. - public EfCoreRepository(IContextProvider provider) - : base(provider) - { - } - - /// - protected override void Dispose(bool disposing) - { - //Context?.Dispose(); - } - - /// - public override IQueryable Queryable() - { - var query = Context.Set().AsQueryable(); - if (Actions.Count > 0) - { - query = Actions.Aggregate(query, (current, action) => action(current)); - } - - return query; - } - - /// - public override async Task GetAsync(TKey key, CancellationToken cancellationToken = default) - { - return await Context.FindAsync(key); - } - - /// - public override async Task GetAsync(Expression> predicate, CancellationToken cancellationToken = default) - { - return await Context.Set().FirstOrDefaultAsync(predicate, cancellationToken); - } - - /// - public override IQueryable Fetch(Expression> predicate) - { - return Queryable().Where(predicate); - } - - /// - public override IQueryable Fetch(Expression> predicate, Action> order) - { - var orderable = new Orderable(Fetch(predicate)); - order(orderable); - return orderable.Queryable; - } - - /// - public override IQueryable Fetch(Expression> predicate, Func, IOrderedQueryable> order) - { - var query = Queryable().Where(predicate); - query = order(query); - - return query; - } - - /// - public override async Task> FetchAsync(Expression> predicate, Action> order, int? page, int? size, CancellationToken cancellationToken = default) - { - var pageIndex = page ?? 1; - var pageSize = size ?? int.MaxValue; - - var handler = new QueryHandler(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(list) { TotalCount = count, PageNumber = pageIndex, PageSize = pageSize }; - } - - /// - public override async Task> FetchAsync(Expression> predicate, Func, IOrderedQueryable> order, int? page, int? size, CancellationToken cancellationToken = default) - { - var pageIndex = page ?? 1; - var pageSize = size ?? int.MaxValue; - - var handler = new QueryHandler(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(list) { TotalCount = count, PageNumber = pageIndex, PageSize = pageSize }; - } - - /// - public override async Task CountAsync(Expression> predicate, CancellationToken cancellationToken = default) - { - return await Context.Set().CountAsync(predicate, cancellationToken); - } - - /// - public override async Task LongCountAsync(Expression> predicate, CancellationToken cancellationToken = default) - { - return await Context.Set().LongCountAsync(predicate, cancellationToken); - } - - /// - public override async Task InsertAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default) - { - var entry = await Context.AddAsync(entity, cancellationToken); - if (autoSave) - { - await SaveChangesAsync(cancellationToken); - } - - return entry.Entity; - } - - /// - public override async Task InsertAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default) - { - await Context.AddRangeAsync(entities, cancellationToken); - if (autoSave) - { - await SaveChangesAsync(cancellationToken); - } - } - - /// - public override async Task UpdateAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default) - { - var _ = Context.Update(entity); - if (autoSave) - { - await SaveChangesAsync(cancellationToken); - } - } - - /// - public override async Task UpdateAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default) - { - Context.UpdateRange(entities); - if (autoSave) - { - await SaveChangesAsync(cancellationToken); - } - } - - /// - public override async Task DeleteAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default) - { - var _ = Context.Remove(entity); - if (autoSave) - { - await SaveChangesAsync(cancellationToken); - } - } - - /// - public override async Task DeleteAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default) - { - Context.RemoveRange(entities); - if (autoSave) - { - await SaveChangesAsync(cancellationToken); - } - } + /// + /// Initializes a new instance of the class. + /// + /// The repository context. + public EfCoreRepository(IContextProvider provider) + : base(provider) + { + } + + /// + protected override void Dispose(bool disposing) + { + //Context?.Dispose(); + } + + /// + public override IQueryable Queryable() + { + var query = Context.Set().AsQueryable(); + if (Actions.Count > 0) + { + query = Actions.Aggregate(query, (current, action) => action(current)); + } + + return query; + } + + /// + public override IQueryable BuildQuery(Expression> predicate, Func, IQueryable> handle) + { + ArgumentNullException.ThrowIfNull(predicate); + var query = Context.Set().AsQueryable(); + if (handle != null) + { + query = handle(query); + } + return query.Where(predicate); + } + + /// + public override async Task GetAsync(TKey key, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(key); + return await Context.FindAsync(key); + } + + /// + public override Task GetAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default) + { + return BuildQuery(predicate, handle).FirstOrDefaultAsync(predicate, cancellationToken); + } + + /// + public override Task> FindAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default) + { + return BuildQuery(predicate, handle).ToListAsync(cancellationToken); + } + + /// + public override Task> FindAsync(Expression> predicate, Func, IQueryable> handle, int offset, int count, CancellationToken cancellationToken = default) + { + return BuildQuery(predicate, handle).Skip(offset).Take(count).ToListAsync(cancellationToken); + } + + /// + public override Task CountAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default) + { + return BuildQuery(predicate, handle).CountAsync(predicate, cancellationToken); + } + + /// + public override Task LongCountAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default) + { + return BuildQuery(predicate, handle).LongCountAsync(predicate, cancellationToken); + } + + /// + public override Task AnyAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default) + { + return BuildQuery(predicate, handle).AnyAsync(predicate, cancellationToken); + } + + /// + public override Task AllAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default) + { + return BuildQuery(predicate, handle).AllAsync(predicate, cancellationToken); + } + + /// + public override async Task 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; + } + + /// + public override async Task InsertAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(entities); + await Context.AddRangeAsync(entities, cancellationToken); + if (autoSave) + { + await SaveChangesAsync(cancellationToken); + } + } + + /// + 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); + } + } + + /// + public override async Task UpdateAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(entities); + Context.UpdateRange(entities); + if (autoSave) + { + await SaveChangesAsync(cancellationToken); + } + } + + /// + 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); + } + } + + /// + public override async Task DeleteAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(entities); + Context.RemoveRange(entities); + if (autoSave) + { + await SaveChangesAsync(cancellationToken); + } + } } \ No newline at end of file diff --git a/Source/Euonia.Repository.Mongo/MongoRepository.cs b/Source/Euonia.Repository.Mongo/MongoRepository.cs index 2305c8c..65cf576 100644 --- a/Source/Euonia.Repository.Mongo/MongoRepository.cs +++ b/Source/Euonia.Repository.Mongo/MongoRepository.cs @@ -2,7 +2,6 @@ using MongoDB.Bson.Serialization; using MongoDB.Driver; using MongoDB.Driver.Linq; -using Nerosoft.Euonia.Collections; using Nerosoft.Euonia.Domain; using Nerosoft.Euonia.Linq; @@ -15,165 +14,140 @@ namespace Nerosoft.Euonia.Repository.Mongo; /// /// public class MongoRepository : Repository - where TKey : IEquatable - where TEntity : class, IEntity - where TContext : MongoDbContext, IRepositoryContext + where TKey : IEquatable + where TEntity : class, IEntity + where TContext : MongoDbContext, IRepositoryContext { - /// - /// Initialize a new instance of with context. - /// - /// - public MongoRepository(IContextProvider provider) - : base(provider) - { - } - - /// - protected override void Dispose(bool disposing) - { - // ignore. - } - - /// - public override IQueryable Queryable() - { - IQueryable query = Context.Collection().AsQueryable(); - if (Actions.Count > 0) - { - query = Actions.Aggregate(query, (current, action) => action(current)); - } - - return query; - } - - /// - public override async Task GetAsync(TKey key, CancellationToken cancellationToken = default) - { - var id = MongoDB.Bson.ObjectId.Parse(key.ToString()); - return await Context.FindAsync(id, cancellationToken); - } - - /// - public override async Task GetAsync(Expression> predicate, CancellationToken cancellationToken = default) - { - var options = new FindOptions { Limit = 1 }; - var query = await Context.FindAsync(predicate, options, cancellationToken); - return await query.FirstOrDefaultAsync(cancellationToken); - } - - /// - public override IQueryable Fetch(Expression> predicate) - { - return System.Linq.Queryable.Where(Context.Collection().AsQueryable(), predicate); - } - - /// - public override IQueryable Fetch(Expression> predicate, Action> order) - { - var orderable = new Orderable(Fetch(predicate)); - order(orderable); - return orderable.Queryable; - } - - /// - public override IQueryable Fetch(Expression> predicate, Func, IOrderedQueryable> order) - { - var query = Queryable().Where(predicate); - query = order(query); - return query; - } - - /// - public override async Task> FetchAsync(Expression> predicate, Action> order, int? page, int? size, CancellationToken cancellationToken = default) - { - var pageIndex = page ?? 1; - var pageSize = size ?? int.MaxValue; - - var handler = new QueryHandler(Queryable()); - - handler.AddCriteria(predicate); - var count = handler.GetCount(); - - handler.SetPage(pageIndex).SetSize(pageSize); - - handler.SetCollator(order); - - var list = await handler.QueryAsync(async query => await ((IMongoQueryable)query).ToListAsync(cancellationToken)); - - return new PageableCollection(list) { TotalCount = count, PageNumber = pageIndex, PageSize = pageSize }; - } - - /// - public override async Task> FetchAsync(Expression> predicate, Func, IOrderedQueryable> order, int? page, int? size, CancellationToken cancellationToken = default) - { - var pageIndex = page ?? 1; - var pageSize = size ?? int.MaxValue; - - var handler = new QueryHandler(Queryable()); - - handler.AddCriteria(predicate); - var count = await handler.GetCountAsync(async query => await ((IMongoQueryable)query).CountAsync(cancellationToken)); - - handler.SetPage(pageIndex).SetSize(pageSize); - - handler.SetCollator(order); - - var list = await handler.QueryAsync(async query => await ((IMongoQueryable)query).ToListAsync(cancellationToken)); - - return new PageableCollection(list) { TotalCount = count, PageNumber = pageIndex, PageSize = pageSize }; - } - - /// - public override async Task CountAsync(Expression> predicate, CancellationToken cancellationToken = default) - { - var result = await Context.Collection().CountDocumentsAsync(predicate, null, cancellationToken); - return (int)result; - } - - /// - public override async Task LongCountAsync(Expression> predicate, CancellationToken cancellationToken = default) - { - var result = await Context.Collection().CountDocumentsAsync(predicate, null, cancellationToken); - return result; - } - - /// - public override async Task InsertAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default) - { - var document = await Context.InsertAsync(entity, cancellationToken); - //var id = document["_id"]; - var result = BsonSerializer.Deserialize(document); - return result; - } - - /// - public override async Task InsertAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default) - { - await Context.InsertAsync(entities, cancellationToken); - } - - /// - public override async Task UpdateAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default) - { - await Context.UpdateAsync(MongoDB.Bson.ObjectId.Parse(entity.Id.ToString()), entity, cancellationToken); - } - - /// - public override async Task UpdateAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default) - { - await Context.UpdateAsync(entities, t => t.Id, cancellationToken); - } - - /// - public override async Task DeleteAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default) - { - await Context.DeleteAsync(MongoDB.Bson.ObjectId.Parse(entity.Id.ToString()), cancellationToken); - } - - /// - public override async Task DeleteAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default) - { - var keys = entities.Select(t => t.Id); - await Context.DeleteAsync(t => keys.Contains(t.Id), cancellationToken); - } + /// + /// Initialize a new instance of with context. + /// + /// + public MongoRepository(IContextProvider provider) + : base(provider) + { + } + + /// + protected override void Dispose(bool disposing) + { + // ignore. + } + + /// + public override IQueryable Queryable() + { + IQueryable query = Context.Collection().AsQueryable(); + if (Actions.Count > 0) + { + query = Actions.Aggregate(query, (current, action) => action(current)); + } + + return query; + } + + /// + public override IQueryable BuildQuery(Expression> predicate, Func, IQueryable> handle) + { + ArgumentNullException.ThrowIfNull(predicate); + IQueryable query = Context.Collection().AsQueryable(); + if (handle != null) + { + query = handle(query); + } + return query.Where(predicate); + } + + /// + public override async Task GetAsync(TKey key, CancellationToken cancellationToken = default) + { + var id = MongoDB.Bson.ObjectId.Parse(key.ToString()); + return await Context.FindAsync(id, cancellationToken); + } + + /// + public override async Task GetAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(predicate); + var options = new FindOptions { Limit = 1 }; + var query = await Context.FindAsync(predicate, options, cancellationToken); + return await query.FirstOrDefaultAsync(cancellationToken); + } + + /// + public override Task> FindAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default) + { + return ((IMongoQueryable)BuildQuery(predicate, handle)).ToListAsync(cancellationToken); + } + + /// + public override Task> FindAsync(Expression> predicate, Func, IQueryable> handle, int offset, int count, CancellationToken cancellationToken = default) + { + return ((IMongoQueryable)BuildQuery(predicate, handle)).Skip(offset).Take(count).ToListAsync(cancellationToken); + } + + /// + public override async Task CountAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default) + { + var result = await Context.Collection().CountDocumentsAsync(predicate, null, cancellationToken); + return (int)result; + } + + /// + public override async Task LongCountAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default) + { + var result = await Context.Collection().CountDocumentsAsync(predicate, null, cancellationToken); + return result; + } + + /// + public override Task AnyAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default) + { + return ((IMongoQueryable)BuildQuery(predicate, handle)).AnyAsync(predicate, cancellationToken); + } + + /// + public override Task AllAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default) + { + return AnyAsync(predicate, handle, cancellationToken).ContinueWith(task => !task.Result, cancellationToken); + } + + /// + public override async Task InsertAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default) + { + var document = await Context.InsertAsync(entity, cancellationToken); + //var id = document["_id"]; + var result = BsonSerializer.Deserialize(document); + return result; + } + + /// + public override async Task InsertAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default) + { + await Context.InsertAsync(entities, cancellationToken); + } + + /// + public override async Task UpdateAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default) + { + await Context.UpdateAsync(MongoDB.Bson.ObjectId.Parse(entity.Id.ToString()), entity, cancellationToken); + } + + /// + public override async Task UpdateAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default) + { + await Context.UpdateAsync(entities, t => t.Id, cancellationToken); + } + + /// + public override async Task DeleteAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default) + { + await Context.DeleteAsync(MongoDB.Bson.ObjectId.Parse(entity.Id.ToString()), cancellationToken); + } + + /// + public override async Task DeleteAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default) + { + var keys = entities.Select(t => t.Id); + await Context.DeleteAsync(t => keys.Contains(t.Id), cancellationToken); + } } \ No newline at end of file diff --git a/Source/Euonia.Repository/Abstracts/IRepository.cs b/Source/Euonia.Repository/Abstracts/IRepository.cs index cecf1bb..cbfc201 100644 --- a/Source/Euonia.Repository/Abstracts/IRepository.cs +++ b/Source/Euonia.Repository/Abstracts/IRepository.cs @@ -10,148 +10,231 @@ namespace Nerosoft.Euonia.Repository; /// /// public interface IRepository : IDisposable - where TEntity : class + where TEntity : class { - /// - /// Gets the actions to be executed before query. - /// - List, IQueryable>> Actions { get; } - - /// - /// Queryable this instance. - /// - /// The all. - IQueryable Queryable(); - - /// - /// Gets an entity with the given primary key value asynchronously. - /// - /// - /// - /// - Task GetAsync(Expression> predicate, CancellationToken cancellationToken = default); - - /// - /// Gets entities matches the specified predicate. - /// - /// The fetch. - /// Predicate. - IQueryable Fetch(Expression> predicate); - - /// - /// Gets entities matches the specified predicate. - /// - /// The fetch. - /// Predicate. - /// Order. - IQueryable Fetch(Expression> predicate, Action> order); - - /// - /// Gets entities matches the specified predicate. - /// - /// The fetch. - /// Predicate. - /// Order. - IQueryable Fetch(Expression> predicate, Func, IOrderedQueryable> order); - - /// - /// - /// - /// - /// - /// - /// - /// - /// - Task> FetchAsync(Expression> predicate, Action> order, int? page, int? size, CancellationToken cancellationToken = default); - - /// - /// - /// - /// - /// - /// - /// - /// - /// - Task> FetchAsync(Expression> predicate, Func, IOrderedQueryable> order, int? page, int? size, CancellationToken cancellationToken = default); - - /// - /// - /// - /// - /// - /// - Task CountAsync(Expression> predicate, CancellationToken cancellationToken = default); - - /// - /// - /// - /// - /// - /// - Task LongCountAsync(Expression> predicate, CancellationToken cancellationToken = default); - - /// - /// Insert a new entity asynchronously. - /// - /// - /// - /// A to observe while waiting for the task to complete. - /// - Task InsertAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default); - - /// - /// Insert multiple new entities asynchronously. - /// - /// - /// - /// A to observe while waiting for the task to complete. - /// - Task InsertAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default); - - /// - /// Update an exists entity asynchronously. - /// - /// The entity. - /// A value indicate that whether the will called automatically. - /// A to observe while waiting for the task to complete. - /// - Task UpdateAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default); - - /// - /// Update multiple exists entities asynchronously. - /// - /// - /// A value indicate that whether the will called automatically. - /// A to observe while waiting for the task to complete. - /// - Task UpdateAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default); - - /// - /// DeleteAsync the specified entity. - /// - /// - /// - /// - /// - Task DeleteAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default); - - /// - /// DeleteAsync the specified entities. - /// - /// - /// - /// - /// - Task DeleteAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default); - - /// - /// Saves the changes async. - /// - /// The changes async. - /// Cancellation token. - Task SaveChangesAsync(CancellationToken cancellationToken = default); + /// + /// Gets the actions to be executed before query. + /// + List, IQueryable>> Actions { get; } + + /// + /// Queryable this instance. + /// + /// The all. + IQueryable Queryable(); + + /// + /// Builds query. + /// + /// + /// + /// + IQueryable BuildQuery(Expression> predicate, Func, IQueryable> handle); + + /// + /// Gets single element that satisfy a condition asynchronously. + /// + /// + /// + /// + Task GetAsync(Expression> predicate, CancellationToken cancellationToken = default) + { + return GetAsync(predicate, null, cancellationToken); + } + + /// + /// Gets single element that satisfy a condition asynchronously. + /// + /// + /// + /// + /// + Task GetAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default); + + /// + /// Finds elements in a sequence that satisfy a condition asynchronously. + /// + /// + /// + /// + Task> FindAsync(Expression> predicate, CancellationToken cancellationToken = default) + { + return FindAsync(predicate, null, cancellationToken); + } + + /// + /// Finds elements in a sequence that satisfy a condition asynchronously. + /// + /// + /// + /// + /// + Task> FindAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default); + + /// + /// Finds elements in a sequence that satisfy a condition asynchronously. + /// + /// + /// + /// + /// + /// + Task> FindAsync(Expression> predicate, int offset, int count, CancellationToken cancellationToken = default) + { + return FindAsync(predicate, null, offset, count, cancellationToken); + } + + /// + /// Finds elements in a sequence that satisfy a condition asynchronously. + /// + /// + /// + /// + /// + /// + /// + Task> FindAsync(Expression> predicate, Func, IQueryable> handle, int offset, int count, CancellationToken cancellationToken = default); + + /// + /// Gets number of elements in a sequence that satisfy a condition asynchronously. + /// + /// + /// + /// + Task CountAsync(Expression> predicate, CancellationToken cancellationToken = default) + { + return CountAsync(predicate, null, cancellationToken); + } + + /// + /// Gets number of elements in a sequence that satisfy a condition asynchronously. + /// + /// + /// + /// + /// + Task CountAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default); + + /// + /// Gets number of elements in a sequence that satisfy a condition asynchronously and returns an value. + /// + /// + /// + /// + Task LongCountAsync(Expression> predicate, CancellationToken cancellationToken = default) + { + return LongCountAsync(predicate, null, cancellationToken); + } + + /// + /// Gets number of elements in a sequence that satisfy a condition asynchronously and returns an value. + /// + /// + /// + /// + /// + Task LongCountAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default); + + /// + /// Determines whether any element of a sequence satisfies a condition asynchronously. + /// + /// The condition. + /// + /// + Task AnyAsync(Expression> predicate, CancellationToken cancellationToken = default) + { + return AnyAsync(predicate, null, cancellationToken); + } + + /// + /// Asynchronously determines whether any element of a sequence satisfies a condition. + /// + /// The condition. + /// + /// + /// + Task AnyAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default); + + /// + /// Asynchronously determines whether all the elements of a sequence satisfy a condition. + /// + /// + /// + /// + Task AllAsync(Expression> predicate, CancellationToken cancellationToken = default) + { + return AllAsync(predicate, null, cancellationToken); + } + + /// + /// Asynchronously determines whether all the elements of a sequence satisfy a condition. + /// + /// + /// + /// + /// + Task AllAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default); + + /// + /// Insert a new entity asynchronously. + /// + /// + /// + /// A to observe while waiting for the task to complete. + /// + Task InsertAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default); + + /// + /// Insert multiple new entities asynchronously. + /// + /// + /// + /// A to observe while waiting for the task to complete. + /// + Task InsertAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default); + + /// + /// Update an exists entity asynchronously. + /// + /// The entity. + /// A value indicate that whether the will called automatically. + /// A to observe while waiting for the task to complete. + /// + Task UpdateAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default); + + /// + /// Update multiple exists entities asynchronously. + /// + /// + /// A value indicate that whether the will called automatically. + /// A to observe while waiting for the task to complete. + /// + Task UpdateAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default); + + /// + /// DeleteAsync the specified entity. + /// + /// + /// + /// + /// + Task DeleteAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default); + + /// + /// DeleteAsync the specified entities. + /// + /// + /// + /// + /// + Task DeleteAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default); + + /// + /// Saves the changes async. + /// + /// The changes async. + /// Cancellation token. + Task SaveChangesAsync(CancellationToken cancellationToken = default); } /// @@ -160,16 +243,60 @@ public interface IRepository : IDisposable /// /// public interface IRepository : IRepository - where TKey : IEquatable - where TEntity : class, IEntity + where TKey : IEquatable + where TEntity : class, IEntity { - /// - /// Gets an entity with the given primary key value asynchronously. - /// - /// The key of entity. - /// - /// - Task GetAsync(TKey key, CancellationToken cancellationToken = default); + /// + /// Gets an entity with the given primary key value asynchronously. + /// + /// The key of entity. + /// + /// + Task GetAsync(TKey key, CancellationToken cancellationToken = default) + { + return GetAsync(key, null, cancellationToken); + } + + /// + /// Gets an entity with the given primary key value asynchronously. + /// + /// + /// + /// + /// + Task GetAsync(TKey key, Func, IQueryable> handle, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(key); + return GetAsync(PredicateBuilder.PropertyEqual(nameof(IEntity.Id), key), handle, cancellationToken); + } + + /// + /// Finds elemets in a sequence with the given primary key values asynchronously. + /// + /// + /// + /// + Task> FindAsync(IEnumerable keys, CancellationToken cancellationToken = default) + { + return FindAsync(keys, null, cancellationToken); + } + + /// + /// Finds elemets in a sequence with the given primary key values asynchronously. + /// + /// + /// + /// + /// + Task> FindAsync(IEnumerable keys, Func, IQueryable> handle, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(keys); + if (!keys.Any()) + { + return Task.FromResult(new List()); + } + return FindAsync(PredicateBuilder.PropertyInRange(nameof(IEntity.Id), keys.ToArray()), handle, cancellationToken); + } } /// @@ -179,13 +306,13 @@ public interface IRepository : IRepository /// The type of entity identifier. /// The type of context. public interface IRepository : IRepository - where TKey : IEquatable - where TEntity : class, IEntity - where TContext : class, IRepositoryContext + where TKey : IEquatable + where TEntity : class, IEntity + where TContext : class, IRepositoryContext { - /// - /// Gets the context. - /// - /// The context. - TContext Context { get; } + /// + /// Gets the context. + /// + /// The context. + TContext Context { get; } } \ No newline at end of file diff --git a/Source/Euonia.Repository/Core/Repository.cs b/Source/Euonia.Repository/Core/Repository.cs index 235a073..0506f0a 100644 --- a/Source/Euonia.Repository/Core/Repository.cs +++ b/Source/Euonia.Repository/Core/Repository.cs @@ -12,87 +12,87 @@ namespace Nerosoft.Euonia.Repository; /// The type of the entity key. /// public abstract class Repository : DisposableObject, IRepository - where TKey : IEquatable - where TEntity : class, IEntity - where TContext : class, IRepositoryContext + where TKey : IEquatable + where TEntity : class, IEntity + where TContext : class, IRepositoryContext { - private readonly IContextProvider _provider; + private readonly IContextProvider _provider; - /// - /// Initialize a new instance of with context. - /// - /// - protected Repository(IContextProvider provider) - { - _provider = provider; - } + /// + /// Initialize a new instance of with context. + /// + /// + protected Repository(IContextProvider provider) + { + _provider = provider; + } - /// - /// Gets the data persistent context. - /// - public TContext Context => _provider.GetContext(); + /// + /// Gets the data persistent context. + /// + public TContext Context => _provider.GetContext(); - /// - public List, IQueryable>> Actions { get; } = new(); + /// + public List, IQueryable>> Actions { get; } = new(); - /// - /// Gets all entities. - /// - /// - public abstract IQueryable Queryable(); + /// + /// Gets all entities. + /// + /// + public abstract IQueryable Queryable(); - /// - public abstract Task GetAsync(TKey key, CancellationToken cancellationToken = default); + /// + public abstract IQueryable BuildQuery(Expression> predicate, Func, IQueryable> handle); - /// - public abstract Task GetAsync(Expression> predicate, CancellationToken cancellationToken = default); + /// + public abstract Task GetAsync(TKey key, CancellationToken cancellationToken = default); - /// - public abstract IQueryable Fetch(Expression> predicate); + /// + public abstract Task GetAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default); - /// - public abstract IQueryable Fetch(Expression> predicate, Action> order); + /// + public abstract Task> FindAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default); - /// - public abstract IQueryable Fetch(Expression> predicate, Func, IOrderedQueryable> order); + /// + public abstract Task> FindAsync(Expression> predicate, Func, IQueryable> handle, int offset, int count, CancellationToken cancellationToken = default); - /// - public abstract Task> FetchAsync(Expression> predicate, Action> order, int? page, int? size, CancellationToken cancellationToken = default); + /// + public abstract Task CountAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default); - /// - public abstract Task> FetchAsync(Expression> predicate, Func, IOrderedQueryable> order, int? page, int? size, CancellationToken cancellationToken = default); + /// + public abstract Task LongCountAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default); - /// - public abstract Task CountAsync(Expression> predicate, CancellationToken cancellationToken = default); + /// + public abstract Task AnyAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default); - /// - public abstract Task LongCountAsync(Expression> predicate, CancellationToken cancellationToken = default); + /// + public abstract Task AllAsync(Expression> predicate, Func, IQueryable> handle, CancellationToken cancellationToken = default); - /// - public abstract Task InsertAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default); + /// + public abstract Task InsertAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default); - /// - public abstract Task InsertAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default); + /// + public abstract Task InsertAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default); - /// - public abstract Task UpdateAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default); + /// + public abstract Task UpdateAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default); - /// - public abstract Task UpdateAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default); + /// + public abstract Task UpdateAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default); - /// - public abstract Task DeleteAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default); + /// + public abstract Task DeleteAsync(TEntity entity, bool autoSave = true, CancellationToken cancellationToken = default); - /// - public abstract Task DeleteAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default); + /// + public abstract Task DeleteAsync(IEnumerable entities, bool autoSave = true, CancellationToken cancellationToken = default); - /// - /// Commit changes asynchronously. - /// - /// The cancellation token. - /// - public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = default) - { - return await Context.SaveChangesAsync(cancellationToken); - } + /// + /// Commit changes asynchronously. + /// + /// The cancellation token. + /// + public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = default) + { + return await Context.SaveChangesAsync(cancellationToken); + } } \ No newline at end of file From 9903fa9ae169d9ee610f257f4055eb75afea5643 Mon Sep 17 00:00:00 2001 From: damon Date: Wed, 17 Jan 2024 22:11:40 +0800 Subject: [PATCH 2/2] Upgrade version to 8.1.19 --- project.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.props b/project.props index 3189a41..54d7d86 100644 --- a/project.props +++ b/project.props @@ -1,6 +1,6 @@ - 8.1.18 + 8.1.19 damon Nerosoft Ltd. Euonia