diff --git a/src/KSFramework/GenericRepository/GenericRepository.cs b/src/KSFramework/GenericRepository/GenericRepository.cs index 448ecd9..afad026 100644 --- a/src/KSFramework/GenericRepository/GenericRepository.cs +++ b/src/KSFramework/GenericRepository/GenericRepository.cs @@ -23,20 +23,24 @@ public GenericRepository(DbContext context) : base(context) /// Gets an entity by its primary key. /// /// The entity ID. + /// /// The entity if found; otherwise, null. - public async ValueTask GetByIdAsync(object id) + public async ValueTask GetByIdAsync(object id, + CancellationToken cancellationToken = default) { - return await DbSet.FindAsync(id); + return await DbSet.FindAsync(id, cancellationToken); } /// /// Gets all entities. /// /// Whether to disable tracking for better performance. + /// /// A list of all entities. - public async Task> GetAllAsync(bool asNoTracking = true) + public async Task> GetAllAsync(bool asNoTracking = true, + CancellationToken cancellationToken = default) { - return await AsQueryable(asNoTracking).ToListAsync(); + return await AsQueryable(asNoTracking).ToListAsync(cancellationToken); } /// @@ -47,11 +51,17 @@ public async Task> GetAllAsync(bool asNoTracking = true) /// Optional filter expression. /// Property name to order by. /// Order descending if true. + /// /// A paginated list of entities. - public async Task> GetPagedAsync(int pageIndex, int pageSize, Expression>? where = null, string? orderBy = "", bool desc = false) + public async Task> GetPagedAsync(int pageIndex, + int pageSize, + Expression>? where = null, + string? orderBy = "", + bool desc = false, + CancellationToken cancellationToken = default) { var query = ApplyWhere(AsQueryable(), where); - return await PaginatedList.CreateAsync(query, pageIndex, pageSize, where, orderBy, desc); + return await PaginatedList.CreateAsync(query, pageIndex, pageSize, where, orderBy, desc, cancellationToken); } /// @@ -84,28 +94,34 @@ public IEnumerable Find(Expression> predicate, bool /// Gets a single entity that matches the given predicate or null. /// /// The filter expression. + /// /// The matching entity or null. - public async Task SingleOrDefaultAsync(Expression> predicate) + public async Task SingleOrDefaultAsync(Expression> predicate, + CancellationToken cancellationToken = default) { - return await DbSet.SingleOrDefaultAsync(predicate); + return await DbSet.SingleOrDefaultAsync(predicate, cancellationToken); } /// /// Adds a new entity asynchronously. /// /// The entity to add. - public async Task AddAsync(TEntity entity) + /// + public async Task AddAsync(TEntity entity, + CancellationToken cancellationToken = default) { - await DbSet.AddAsync(entity); + await DbSet.AddAsync(entity, cancellationToken); } /// /// Adds a range of entities asynchronously. /// /// The entities to add. - public async Task AddRangeAsync(IEnumerable entities) + /// + public async Task AddRangeAsync(IEnumerable entities, + CancellationToken cancellationToken = default) { - await DbSet.AddRangeAsync(entities); + await DbSet.AddRangeAsync(entities, cancellationToken); } /// @@ -139,9 +155,11 @@ public void RemoveRange(IEnumerable entities) /// Determines whether any entity exists that matches the specified predicate. /// /// The condition to check. + /// /// True if at least one entity exists; otherwise, false. - public async Task IsExistValueForPropertyAsync(Expression> predicate) + public async Task IsExistValueForPropertyAsync(Expression> predicate, + CancellationToken cancellationToken = default) { - return await DbSet.AnyAsync(predicate); + return await DbSet.AnyAsync(predicate, cancellationToken); } } \ No newline at end of file diff --git a/src/KSFramework/GenericRepository/IGenericRepository.cs b/src/KSFramework/GenericRepository/IGenericRepository.cs index 52cd222..da8dcc5 100644 --- a/src/KSFramework/GenericRepository/IGenericRepository.cs +++ b/src/KSFramework/GenericRepository/IGenericRepository.cs @@ -13,15 +13,17 @@ public interface IGenericRepository where TEntity : class /// Asynchronously retrieves an entity by its unique identifier. /// /// The unique identifier of the entity. + /// /// A task representing the asynchronous operation, containing the entity if found; otherwise, null. - ValueTask GetByIdAsync(object id); + ValueTask GetByIdAsync(object id, CancellationToken cancellationToken = default); /// /// Asynchronously retrieves all entities. /// /// Whether to track entities in change tracker. + /// /// A task containing all entities. - Task> GetAllAsync(bool asNoTracking = true); + Task> GetAllAsync(bool asNoTracking = true, CancellationToken cancellationToken = default); /// /// Asynchronously retrieves a paginated list of entities with optional filtering and ordering. @@ -31,13 +33,15 @@ public interface IGenericRepository where TEntity : class /// Optional filter expression. /// Optional property name to order by. /// Indicates if the order should be descending. + /// /// A task containing a paginated list of entities. Task> GetPagedAsync( int pageIndex, int pageSize, Expression>? where = null, string? orderBy = "", - bool desc = false); + bool desc = false, + CancellationToken cancellationToken = default); /// /// Retrieves a paginated list of entities with optional filtering and ordering. @@ -68,19 +72,21 @@ PaginatedList GetPaged( /// /// The condition to match. /// A task containing a single entity or null. - Task SingleOrDefaultAsync(Expression> predicate); + Task SingleOrDefaultAsync(Expression> predicate, CancellationToken cancellationToken = default); /// /// Asynchronously adds an entity to the repository. /// /// The entity to add. - Task AddAsync(TEntity entity); + /// + Task AddAsync(TEntity entity, CancellationToken cancellationToken = default); /// /// Asynchronously adds multiple entities to the repository. /// /// The entities to add. - Task AddRangeAsync(IEnumerable entities); + /// + Task AddRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default); /// /// Updates an existing entity in the repository. @@ -104,6 +110,8 @@ PaginatedList GetPaged( /// Asynchronously checks whether any entity matches the given predicate. /// /// The condition to match. + /// /// True if any entity matches; otherwise, false. - Task IsExistValueForPropertyAsync(Expression> predicate); + Task IsExistValueForPropertyAsync(Expression> predicate, + CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/KSFramework/GenericRepository/IRepository.cs b/src/KSFramework/GenericRepository/IRepository.cs index 75bdaef..d099325 100644 --- a/src/KSFramework/GenericRepository/IRepository.cs +++ b/src/KSFramework/GenericRepository/IRepository.cs @@ -9,10 +9,13 @@ namespace KSFramework.GenericRepository; /// The entity type. public interface IRepository where TEntity : class { - Task AddAsync(TEntity entity); - Task AddRangeAsync(IEnumerable entities); + Task AddAsync(TEntity entity, + CancellationToken cancellationToken = default); + Task AddRangeAsync(IEnumerable entities, + CancellationToken cancellationToken = default); IEnumerable Find(Expression> predicate, bool asNoTracking = true); - Task> GetAllAsync(bool asNoTracking = true); + Task> GetAllAsync(bool asNoTracking = true, + CancellationToken cancellationToken = default); Task> GetPagedAsync( int pageIndex, int pageSize, @@ -25,10 +28,13 @@ PaginatedList GetPaged( Expression>? where = null, string? orderBy = "", bool desc = false); - ValueTask GetByIdAsync(object id); + ValueTask GetByIdAsync(object id, + CancellationToken cancellationToken = default); void Remove(TEntity entity); void RemoveRange(IEnumerable entities); - Task SingleOrDefaultAsync(Expression> predicate); - Task IsExistValueForPropertyAsync(Expression> predicate); + Task SingleOrDefaultAsync(Expression> predicate, + CancellationToken cancellationToken = default); + Task IsExistValueForPropertyAsync(Expression> predicate, + CancellationToken cancellationToken = default); void Update(TEntity entity); } \ No newline at end of file diff --git a/src/KSFramework/Pagination/PaginatedList.cs b/src/KSFramework/Pagination/PaginatedList.cs index 7a053a8..470a8f5 100644 --- a/src/KSFramework/Pagination/PaginatedList.cs +++ b/src/KSFramework/Pagination/PaginatedList.cs @@ -37,8 +37,14 @@ public bool HasNextPage } } - public static async Task> CreateAsync(IQueryable source, int pageIndex, int pageSize, Expression>? where = null, - string? orderBy = "", bool desc = false) + public static async Task> CreateAsync( + IQueryable source, + int pageIndex, + int pageSize, + Expression>? where = null, + string? orderBy = "", + bool desc = false, + CancellationToken cancellationToken = default) { if(where is null) where = x => true; @@ -54,8 +60,8 @@ public static async Task> CreateAsync(IQueryable source, int } } - var count = await source.CountAsync(where); - var items = await source.Where(where).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(); + var count = await source.CountAsync(where, cancellationToken); + var items = await source.Where(where).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(cancellationToken); return new PaginatedList(items, count, pageIndex, pageSize); }