// Protected methods protected virtual async Task ProcessBatch(List <BatchItem <TKey, TEntity> > batch, CancellationToken cancellationToken) { await using var dbContext = CreateDbContext(); var keys = new HashSet <TKey>(); foreach (var item in batch) { if (!item.TryCancel(cancellationToken)) { keys.Add(item.Input); } } var pEntity = Expression.Parameter(typeof(TEntity), "e"); var eKey = KeyExtractorExpressionBuilder.Invoke(pEntity); var eBody = Expression.Call(Expression.Constant(keys), ContainsMethod, eKey); var eLambda = (Expression <Func <TEntity, bool> >)Expression.Lambda(eBody, pEntity); var query = QueryTransformer.Invoke(dbContext.Set <TEntity>().Where(eLambda)); var entities = await query .ToDictionaryAsync(KeyExtractor, cancellationToken) .ConfigureAwait(false); PostProcessor.Invoke(entities); foreach (var item in batch) { entities.TryGetValue(item.Input, out var entity); item.SetResult(Result.Value(entity) !, CancellationToken.None); } }