Skip to content

Commit b7abd78

Browse files
authored
Merge pull request #46 from A-Programmer/feature/Add_BlogApp_to_Solution
Add CancellationToken to Repository methods
2 parents 839e451 + 1e212d6 commit b7abd78

File tree

4 files changed

+69
-31
lines changed

4 files changed

+69
-31
lines changed

src/KSFramework/GenericRepository/GenericRepository.cs

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,24 @@ public GenericRepository(DbContext context) : base(context)
2323
/// Gets an entity by its primary key.
2424
/// </summary>
2525
/// <param name="id">The entity ID.</param>
26+
/// <param name="cancellationToken"></param>
2627
/// <returns>The entity if found; otherwise, null.</returns>
27-
public async ValueTask<TEntity?> GetByIdAsync(object id)
28+
public async ValueTask<TEntity?> GetByIdAsync(object id,
29+
CancellationToken cancellationToken = default)
2830
{
29-
return await DbSet.FindAsync(id);
31+
return await DbSet.FindAsync(id, cancellationToken);
3032
}
3133

3234
/// <summary>
3335
/// Gets all entities.
3436
/// </summary>
3537
/// <param name="asNoTracking">Whether to disable tracking for better performance.</param>
38+
/// <param name="cancellationToken"></param>
3639
/// <returns>A list of all entities.</returns>
37-
public async Task<IEnumerable<TEntity>> GetAllAsync(bool asNoTracking = true)
40+
public async Task<IEnumerable<TEntity>> GetAllAsync(bool asNoTracking = true,
41+
CancellationToken cancellationToken = default)
3842
{
39-
return await AsQueryable(asNoTracking).ToListAsync();
43+
return await AsQueryable(asNoTracking).ToListAsync(cancellationToken);
4044
}
4145

4246
/// <summary>
@@ -47,11 +51,17 @@ public async Task<IEnumerable<TEntity>> GetAllAsync(bool asNoTracking = true)
4751
/// <param name="where">Optional filter expression.</param>
4852
/// <param name="orderBy">Property name to order by.</param>
4953
/// <param name="desc">Order descending if true.</param>
54+
/// <param name="cancellationToken"></param>
5055
/// <returns>A paginated list of entities.</returns>
51-
public async Task<PaginatedList<TEntity>> GetPagedAsync(int pageIndex, int pageSize, Expression<Func<TEntity, bool>>? where = null, string? orderBy = "", bool desc = false)
56+
public async Task<PaginatedList<TEntity>> GetPagedAsync(int pageIndex,
57+
int pageSize,
58+
Expression<Func<TEntity, bool>>? where = null,
59+
string? orderBy = "",
60+
bool desc = false,
61+
CancellationToken cancellationToken = default)
5262
{
5363
var query = ApplyWhere(AsQueryable(), where);
54-
return await PaginatedList<TEntity>.CreateAsync(query, pageIndex, pageSize, where, orderBy, desc);
64+
return await PaginatedList<TEntity>.CreateAsync(query, pageIndex, pageSize, where, orderBy, desc, cancellationToken);
5565
}
5666

5767
/// <summary>
@@ -84,28 +94,34 @@ public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate, bool
8494
/// Gets a single entity that matches the given predicate or null.
8595
/// </summary>
8696
/// <param name="predicate">The filter expression.</param>
97+
/// <param name="cancellationToken"></param>
8798
/// <returns>The matching entity or null.</returns>
88-
public async Task<TEntity?> SingleOrDefaultAsync(Expression<Func<TEntity, bool>> predicate)
99+
public async Task<TEntity?> SingleOrDefaultAsync(Expression<Func<TEntity, bool>> predicate,
100+
CancellationToken cancellationToken = default)
89101
{
90-
return await DbSet.SingleOrDefaultAsync(predicate);
102+
return await DbSet.SingleOrDefaultAsync(predicate, cancellationToken);
91103
}
92104

93105
/// <summary>
94106
/// Adds a new entity asynchronously.
95107
/// </summary>
96108
/// <param name="entity">The entity to add.</param>
97-
public async Task AddAsync(TEntity entity)
109+
/// <param name="cancellationToken"></param>
110+
public async Task AddAsync(TEntity entity,
111+
CancellationToken cancellationToken = default)
98112
{
99-
await DbSet.AddAsync(entity);
113+
await DbSet.AddAsync(entity, cancellationToken);
100114
}
101115

102116
/// <summary>
103117
/// Adds a range of entities asynchronously.
104118
/// </summary>
105119
/// <param name="entities">The entities to add.</param>
106-
public async Task AddRangeAsync(IEnumerable<TEntity> entities)
120+
/// <param name="cancellationToken"></param>
121+
public async Task AddRangeAsync(IEnumerable<TEntity> entities,
122+
CancellationToken cancellationToken = default)
107123
{
108-
await DbSet.AddRangeAsync(entities);
124+
await DbSet.AddRangeAsync(entities, cancellationToken);
109125
}
110126

111127
/// <summary>
@@ -139,9 +155,11 @@ public void RemoveRange(IEnumerable<TEntity> entities)
139155
/// Determines whether any entity exists that matches the specified predicate.
140156
/// </summary>
141157
/// <param name="predicate">The condition to check.</param>
158+
/// <param name="cancellationToken"></param>
142159
/// <returns>True if at least one entity exists; otherwise, false.</returns>
143-
public async Task<bool> IsExistValueForPropertyAsync(Expression<Func<TEntity, bool>> predicate)
160+
public async Task<bool> IsExistValueForPropertyAsync(Expression<Func<TEntity, bool>> predicate,
161+
CancellationToken cancellationToken = default)
144162
{
145-
return await DbSet.AnyAsync(predicate);
163+
return await DbSet.AnyAsync(predicate, cancellationToken);
146164
}
147165
}

src/KSFramework/GenericRepository/IGenericRepository.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,17 @@ public interface IGenericRepository<TEntity> where TEntity : class
1313
/// Asynchronously retrieves an entity by its unique identifier.
1414
/// </summary>
1515
/// <param name="id">The unique identifier of the entity.</param>
16+
/// <param name="cancellationToken"></param>
1617
/// <returns>A task representing the asynchronous operation, containing the entity if found; otherwise, null.</returns>
17-
ValueTask<TEntity?> GetByIdAsync(object id);
18+
ValueTask<TEntity?> GetByIdAsync(object id, CancellationToken cancellationToken = default);
1819

1920
/// <summary>
2021
/// Asynchronously retrieves all entities.
2122
/// </summary>
2223
/// <param name="asNoTracking">Whether to track entities in change tracker.</param>
24+
/// <param name="cancellationToken"></param>
2325
/// <returns>A task containing all entities.</returns>
24-
Task<IEnumerable<TEntity>> GetAllAsync(bool asNoTracking = true);
26+
Task<IEnumerable<TEntity>> GetAllAsync(bool asNoTracking = true, CancellationToken cancellationToken = default);
2527

2628
/// <summary>
2729
/// Asynchronously retrieves a paginated list of entities with optional filtering and ordering.
@@ -31,13 +33,15 @@ public interface IGenericRepository<TEntity> where TEntity : class
3133
/// <param name="where">Optional filter expression.</param>
3234
/// <param name="orderBy">Optional property name to order by.</param>
3335
/// <param name="desc">Indicates if the order should be descending.</param>
36+
/// <param name="cancellationToken"></param>
3437
/// <returns>A task containing a paginated list of entities.</returns>
3538
Task<PaginatedList<TEntity>> GetPagedAsync(
3639
int pageIndex,
3740
int pageSize,
3841
Expression<Func<TEntity, bool>>? where = null,
3942
string? orderBy = "",
40-
bool desc = false);
43+
bool desc = false,
44+
CancellationToken cancellationToken = default);
4145

4246
/// <summary>
4347
/// Retrieves a paginated list of entities with optional filtering and ordering.
@@ -68,19 +72,21 @@ PaginatedList<TEntity> GetPaged(
6872
/// </summary>
6973
/// <param name="predicate">The condition to match.</param>
7074
/// <returns>A task containing a single entity or null.</returns>
71-
Task<TEntity?> SingleOrDefaultAsync(Expression<Func<TEntity, bool>> predicate);
75+
Task<TEntity?> SingleOrDefaultAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default);
7276

7377
/// <summary>
7478
/// Asynchronously adds an entity to the repository.
7579
/// </summary>
7680
/// <param name="entity">The entity to add.</param>
77-
Task AddAsync(TEntity entity);
81+
/// <param name="cancellationToken"></param>
82+
Task AddAsync(TEntity entity, CancellationToken cancellationToken = default);
7883

7984
/// <summary>
8085
/// Asynchronously adds multiple entities to the repository.
8186
/// </summary>
8287
/// <param name="entities">The entities to add.</param>
83-
Task AddRangeAsync(IEnumerable<TEntity> entities);
88+
/// <param name="cancellationToken"></param>
89+
Task AddRangeAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default);
8490

8591
/// <summary>
8692
/// Updates an existing entity in the repository.
@@ -104,6 +110,8 @@ PaginatedList<TEntity> GetPaged(
104110
/// Asynchronously checks whether any entity matches the given predicate.
105111
/// </summary>
106112
/// <param name="predicate">The condition to match.</param>
113+
/// <param name="cancellationToken"></param>
107114
/// <returns>True if any entity matches; otherwise, false.</returns>
108-
Task<bool> IsExistValueForPropertyAsync(Expression<Func<TEntity, bool>> predicate);
115+
Task<bool> IsExistValueForPropertyAsync(Expression<Func<TEntity, bool>> predicate,
116+
CancellationToken cancellationToken = default);
109117
}

src/KSFramework/GenericRepository/IRepository.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ namespace KSFramework.GenericRepository;
99
/// <typeparam name="TEntity">The entity type.</typeparam>
1010
public interface IRepository<TEntity> where TEntity : class
1111
{
12-
Task AddAsync(TEntity entity);
13-
Task AddRangeAsync(IEnumerable<TEntity> entities);
12+
Task AddAsync(TEntity entity,
13+
CancellationToken cancellationToken = default);
14+
Task AddRangeAsync(IEnumerable<TEntity> entities,
15+
CancellationToken cancellationToken = default);
1416
IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate, bool asNoTracking = true);
15-
Task<IEnumerable<TEntity>> GetAllAsync(bool asNoTracking = true);
17+
Task<IEnumerable<TEntity>> GetAllAsync(bool asNoTracking = true,
18+
CancellationToken cancellationToken = default);
1619
Task<PaginatedList<TEntity>> GetPagedAsync(
1720
int pageIndex,
1821
int pageSize,
@@ -25,10 +28,13 @@ PaginatedList<TEntity> GetPaged(
2528
Expression<Func<TEntity, bool>>? where = null,
2629
string? orderBy = "",
2730
bool desc = false);
28-
ValueTask<TEntity?> GetByIdAsync(object id);
31+
ValueTask<TEntity?> GetByIdAsync(object id,
32+
CancellationToken cancellationToken = default);
2933
void Remove(TEntity entity);
3034
void RemoveRange(IEnumerable<TEntity> entities);
31-
Task<TEntity?> SingleOrDefaultAsync(Expression<Func<TEntity, bool>> predicate);
32-
Task<bool> IsExistValueForPropertyAsync(Expression<Func<TEntity, bool>> predicate);
35+
Task<TEntity?> SingleOrDefaultAsync(Expression<Func<TEntity, bool>> predicate,
36+
CancellationToken cancellationToken = default);
37+
Task<bool> IsExistValueForPropertyAsync(Expression<Func<TEntity, bool>> predicate,
38+
CancellationToken cancellationToken = default);
3339
void Update(TEntity entity);
3440
}

src/KSFramework/Pagination/PaginatedList.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,14 @@ public bool HasNextPage
3737
}
3838
}
3939

40-
public static async Task<PaginatedList<T>> CreateAsync(IQueryable<T> source, int pageIndex, int pageSize, Expression<Func<T, bool>>? where = null,
41-
string? orderBy = "", bool desc = false)
40+
public static async Task<PaginatedList<T>> CreateAsync(
41+
IQueryable<T> source,
42+
int pageIndex,
43+
int pageSize,
44+
Expression<Func<T, bool>>? where = null,
45+
string? orderBy = "",
46+
bool desc = false,
47+
CancellationToken cancellationToken = default)
4248
{
4349
if(where is null) where = x => true;
4450

@@ -54,8 +60,8 @@ public static async Task<PaginatedList<T>> CreateAsync(IQueryable<T> source, int
5460
}
5561
}
5662

57-
var count = await source.CountAsync(where);
58-
var items = await source.Where(where).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
63+
var count = await source.CountAsync(where, cancellationToken);
64+
var items = await source.Where(where).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(cancellationToken);
5965
return new PaginatedList<T>(items, count, pageIndex, pageSize);
6066
}
6167

0 commit comments

Comments
 (0)