public async Task <bool> MoveNext(CancellationToken cancellationToken) { if (_dataReader == null) { await _relationalQueryContext.Connection.OpenAsync(cancellationToken); try { var relationalCommand = _shaperCommandContext .GetRelationalCommand(_relationalQueryContext.ParameterValues, _relationalQueryContext); _dataReader = await relationalCommand.ExecuteReaderAsync( _relationalQueryContext.Connection, _relationalQueryContext.ParameterValues, _relationalQueryContext.CommandLogger, cancellationToken); } catch { // If failure happens creating the data reader, then it won't be available to // handle closing the connection, so do it explicitly here to preserve ref counting. _relationalQueryContext.Connection.Close(); throw; } _dbDataReader = _dataReader.DbDataReader; } using (await _relationalQueryContext.ConcurrencyDetector .EnterCriticalSectionAsync(cancellationToken)) { bool hasNext; try { hasNext = await _dbDataReader.ReadAsync(cancellationToken); } catch (Exception exception) { _logger.QueryIterationFailed(_contextType, exception); throw; } Current = hasNext ? _materializer(_dbDataReader, _relationalQueryContext.Context) : default; return(hasNext); } }
// ReSharper disable once InconsistentNaming private static IEnumerable <TEntity> _FastQuery <TEntity>( RelationalQueryContext relationalQueryContext, ShaperCommandContext shaperCommandContext, Func <DbDataReader, DbContext, TEntity> materializer, Type contextType, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { relationalQueryContext.Connection.Open(); RelationalDataReader dataReader; try { var relationalCommand = shaperCommandContext .GetRelationalCommand(relationalQueryContext.ParameterValues, relationalQueryContext); dataReader = relationalCommand.ExecuteReader( relationalQueryContext.Connection, relationalQueryContext.ParameterValues, relationalQueryContext.CommandLogger); } catch { // If failure happens creating the data reader, then it won't be available to // handle closing the connection, so do it explicitly here to preserve ref counting. relationalQueryContext.Connection.Close(); throw; } var dbDataReader = dataReader.DbDataReader; try { using (dataReader) { using (relationalQueryContext.ConcurrencyDetector.EnterCriticalSection()) // TODO: IDisposable box? { while (true) { bool hasNext; try { hasNext = dataReader.Read(); } catch (Exception exception) { logger.QueryIterationFailed(contextType, exception); throw; } if (hasNext) { yield return(materializer(dbDataReader, relationalQueryContext.Context)); } else { yield break; } } } } } finally { relationalQueryContext.Connection?.Close(); relationalQueryContext.Dispose(); } }