// Protected methods

        protected virtual async Task ProcessBatchAsync(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 entities = await dbContext.Set <TEntity>()
                           .Where(eLambda)
                           .ToDictionaryAsync(KeyExtractor, cancellationToken)
                           .ConfigureAwait(false);

            foreach (var item in batch)
            {
                entities.TryGetValue(item.Input, out var entity);
                item.SetResult(Result.Value(entity) !, CancellationToken.None);
            }
        }
        public DbEntityResolver(Options?options, IServiceProvider services) : base(services)
        {
            options ??= new();
            BatchProcessorFactory = options.BatchProcessorFactory ??
                                    (self => new AsyncBatchProcessor <TKey, TEntity> {
                MaxBatchSize = 16,
                ConcurrencyLevel = Math.Min(HardwareInfo.ProcessorCount, 4),
                BatchingDelayTaskFactory = cancellationToken => Task.Delay(1, cancellationToken),
                BatchProcessor = self.ProcessBatch,
            });
            _batchProcessorLazy = new Lazy <AsyncBatchProcessor <TKey, TEntity> >(
                () => BatchProcessorFactory.Invoke(this));

            using var dbContext = CreateDbContext();
            var entityType = dbContext.Model.FindEntityType(typeof(TEntity));
            var key        = entityType.FindPrimaryKey();

            KeyExtractorExpressionBuilder = options.KeyExtractorExpressionBuilder ??
                                            (eEntity => Expression.PropertyOrField(eEntity, key.Properties.Single().Name));
            var pEntity = Expression.Parameter(typeof(TEntity), "e");
            var eBody   = KeyExtractorExpressionBuilder.Invoke(pEntity);

            KeyExtractor = (Func <TEntity, TKey>)Expression.Lambda(eBody, pEntity).Compile();

            QueryTransformer = options.QueryTransformer ?? (q => q);
            PostProcessor    = options.PostProcessor ?? (_ => {});
        }