Add predicate to ExecuteUpdateAsync
Closed this issue · 3 comments
ExecuteUpdateAsync
of EFCore rely on the source IQueryable
has already been filtered by Where
Linq, but in your version, i can not see anywhere to add filter for your repository, which mean whenever we call something like
await repository.ExecuteUpdateAsync<Person>(
sp => sp.SetProperty(t => t.IsDeleted, true)
)
// translate to
/*
UPDATE People SET IsDeleted = true;
*/
whole record will get updated immediately, maybe you can add an predicate to your ExecuteUpdateAsync
to let consumer supply their own filter condition just like what we can do in EFCore
await context.People
.Where(p => p.CreatedDate <= DateTime.Now.AddDays(-30))
.ExecuteUpdateAsync(sp => sp => sp.SetProperty(t => t.IsDeleted, true)) );
// now we have where clause
/*
UPDATE People SET IsDeleted = false
WHERE CreatedDate <= @p__linq__0;
*/
Browsing around source code i find your implementation like this
public async Task<int> ExecuteUpdateAsync<TEntity>(
Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls,
CancellationToken cancellationToken = default)
where TEntity : class
{
int count = await _dbContext.Set<TEntity>().ExecuteUpdateAsync(setPropertyCalls, cancellationToken);
return count;
}
So instead of calling ExecuteUpdateAsync
directly in DbSet
, you can change function a little like so
public async Task<int> ExecuteUpdateAsync<TEntity>(
Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls,
Expression<Func<TEntity, bool>>? predicate = null
CancellationToken cancellationToken = default)
where TEntity : class
{
var dbSet = _dbContext.Set<TEntity>();
if (predicate != null) dbSet = dbSet.Where(predicate);
return await dbSet.ExecuteUpdateAsync(setPropertyCalls, cancellationToken);
}
Anyway, your library is already good, filter in ExecuteUpdateAsync
is some niche thing
@NotAsea Thank you so much for reaching out. Surely I am taking care of it.
closing as @TanvirArjel has already had planned for it