public void Dispose() { if (!_disposed) { try { _relationalQueryContext.Connection.Semaphore.Wait(); if (_dataReader != null) { _dataReader.Dispose(); _dataReader = null; _dbDataReader = null; _relationalQueryContext.Connection?.Close(); } _disposed = true; } finally { _relationalQueryContext.Connection.Semaphore.Release(); } _relationalQueryContext.Dispose(); } }
// 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(); } }