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();
                    }
                }
Exemplo n.º 2
0
        // 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();
            }
        }