/// <summary>
        ///    The method called by other methods on this type to execute synchronously.
        /// </summary>
        /// <param name="connection"> The connection to use. </param>
        /// <param name="executeMethod"> The method type. </param>
        /// <param name="parameterValues"> The parameter values. </param>
        /// <param name="logger"> The command logger. </param>
        /// <param name="cancellationToken"> The cancellation token. </param>
        /// <returns> The result of the execution. </returns>
        protected virtual async Task <object> ExecuteAsync(
            [NotNull] IRelationalConnection connection,
            DbCommandMethod executeMethod,
            [CanBeNull] IReadOnlyDictionary <string, object> parameterValues,
            [CanBeNull] IDiagnosticsLogger <DbLoggerCategory.Database.Command> logger,
            CancellationToken cancellationToken = default)
        {
            Check.NotNull(connection, nameof(connection));

            var dbCommand = CreateCommand(connection, parameterValues);

            await connection.OpenAsync(cancellationToken);

            var commandId = Guid.NewGuid();

            var startTime = DateTimeOffset.UtcNow;
            var stopwatch = Stopwatch.StartNew();

            logger?.CommandExecuting(
                dbCommand,
                executeMethod,
                commandId,
                connection.ConnectionId,
                async: true,
                startTime: startTime);

            object result;
            var    readerOpen = false;

            try
            {
                switch (executeMethod)
                {
                case DbCommandMethod.ExecuteNonQuery:
                {
                    result = await dbCommand.ExecuteNonQueryAsync(cancellationToken);

                    break;
                }

                case DbCommandMethod.ExecuteScalar:
                {
                    result = await dbCommand.ExecuteScalarAsync(cancellationToken);

                    break;
                }

                case DbCommandMethod.ExecuteReader:
                {
                    result = new RelationalDataReader(
                        connection,
                        dbCommand,
                        await dbCommand.ExecuteReaderAsync(cancellationToken),
                        commandId,
                        logger);
                    readerOpen = true;

                    break;
                }

                default:
                {
                    throw new NotSupportedException();
                }
                }

                logger?.CommandExecuted(
                    dbCommand,
                    executeMethod,
                    commandId,
                    connection.ConnectionId,
                    result,
                    true,
                    startTime,
                    stopwatch.Elapsed);
            }
            catch (Exception exception)
            {
                logger?.CommandError(
                    dbCommand,
                    executeMethod,
                    commandId,
                    connection.ConnectionId,
                    exception,
                    true,
                    startTime,
                    stopwatch.Elapsed);

                throw;
            }
            finally
            {
                if (!readerOpen)
                {
                    dbCommand.Parameters.Clear();
                    dbCommand.Dispose();
                    connection.Close();
                }
            }

            return(result);
        }
Example #2
0
        /// <summary>
        ///     Executes the command with a <see cref="RelationalDataReader" /> result.
        /// </summary>
        /// <param name="parameterObject"> Parameters for this method. </param>
        /// <returns> The result of the command. </returns>
        public virtual RelationalDataReader ExecuteReader(RelationalCommandParameterObject parameterObject)
        {
            var(connection, context, logger) = (parameterObject.Connection, parameterObject.Context, parameterObject.Logger);

            var commandId = Guid.NewGuid();
            var command   = CreateCommand(parameterObject, commandId, DbCommandMethod.ExecuteReader);

            connection.Open();

            var startTime = DateTimeOffset.UtcNow;
            var stopwatch = Stopwatch.StartNew();

            var readerOpen = false;

            try
            {
                var interceptionResult = logger?.CommandReaderExecuting(
                    connection,
                    command,
                    context,
                    commandId,
                    connection.ConnectionId,
                    startTime)
                                         ?? default;

                var reader = interceptionResult.HasResult
                    ? interceptionResult.Result
                    : command.ExecuteReader();

                if (logger != null)
                {
                    reader = logger.CommandReaderExecuted(
                        connection,
                        command,
                        context,
                        commandId,
                        connection.ConnectionId,
                        reader,
                        startTime,
                        stopwatch.Elapsed);
                }

                var result = new RelationalDataReader(
                    connection,
                    command,
                    reader,
                    commandId,
                    logger);

                readerOpen = true;

                return(result);
            }
            catch (Exception exception)
            {
                logger?.CommandError(
                    connection,
                    command,
                    context,
                    DbCommandMethod.ExecuteReader,
                    commandId,
                    connection.ConnectionId,
                    exception,
                    startTime,
                    stopwatch.Elapsed);

                throw;
            }
            finally
            {
                if (!readerOpen)
                {
                    CleanupCommand(command, connection);
                }
            }
        }
Example #3
0
        /// <summary>
        ///     Asynchronously executes the command with a <see cref="RelationalDataReader" /> result.
        /// </summary>
        /// <param name="parameterObject"> Parameters for this method. </param>
        /// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
        /// <returns>
        ///     A task that represents the asynchronous operation. The task result contains the result of the command.
        /// </returns>
        public virtual async Task <RelationalDataReader> ExecuteReaderAsync(
            RelationalCommandParameterObject parameterObject,
            CancellationToken cancellationToken = default)
        {
            var(connection, context, logger) = (parameterObject.Connection, parameterObject.Context, parameterObject.Logger);

            var commandId = Guid.NewGuid();
            var command   = CreateCommand(parameterObject, commandId, DbCommandMethod.ExecuteReader);

            await connection.OpenAsync(cancellationToken);

            var startTime = DateTimeOffset.UtcNow;
            var stopwatch = Stopwatch.StartNew();

            var readerOpen = false;

            try
            {
                var interceptionResult = logger == null
                    ? default
                    : await logger.CommandReaderExecutingAsync(
                    connection,
                    command,
                    context,
                    commandId,
                    connection.ConnectionId,
                    startTime,
                    cancellationToken);

                var reader = interceptionResult.HasResult
                    ? interceptionResult.Result
                    : await command.ExecuteReaderAsync(cancellationToken);

                if (logger != null)
                {
                    reader = await logger.CommandReaderExecutedAsync(
                        connection,
                        command,
                        context,
                        commandId,
                        connection.ConnectionId,
                        reader,
                        startTime,
                        stopwatch.Elapsed,
                        cancellationToken);
                }

                var result = new RelationalDataReader(
                    connection,
                    command,
                    reader,
                    commandId,
                    logger);

                readerOpen = true;

                return(result);
            }
            catch (Exception exception)
            {
                if (logger != null)
                {
                    await logger.CommandErrorAsync(
                        connection,
                        command,
                        context,
                        DbCommandMethod.ExecuteReader,
                        commandId,
                        connection.ConnectionId,
                        exception,
                        startTime,
                        stopwatch.Elapsed,
                        cancellationToken);
                }

                throw;
            }
            finally
            {
                if (!readerOpen)
                {
                    await CleanupCommandAsync(command, connection);
                }
            }
        }
Example #4
0
        /// <summary>
        ///    The method called by other methods on this type to execute synchronously.
        /// </summary>
        /// <param name="connection"> The connection to use. </param>
        /// <param name="executeMethod"> The method type. </param>
        /// <param name="parameterValues"> The parameter values. </param>
        /// <param name="logger"> The command logger. </param>
        /// <returns> The result of the execution. </returns>
        protected virtual object Execute(
            [NotNull] IRelationalConnection connection,
            DbCommandMethod executeMethod,
            [CanBeNull] IReadOnlyDictionary <string, object> parameterValues,
            [CanBeNull] IDiagnosticsLogger <DbLoggerCategory.Database.Command> logger)
        {
            Check.NotNull(connection, nameof(connection));

            var dbCommand = CreateCommand(connection, parameterValues);

            connection.Open();

            var commandId = Guid.NewGuid();

            var startTime = DateTimeOffset.UtcNow;
            var stopwatch = Stopwatch.StartNew();

            object result;
            var    readerOpen = false;

            try
            {
                switch (executeMethod)
                {
                case DbCommandMethod.ExecuteNonQuery:
                    var nonQueryResult = (logger?.CommandNonQueryExecuting(
                                              dbCommand,
                                              commandId,
                                              connection.ConnectionId,
                                              startTime: startTime)
                                          ?? new InterceptionResult <int>(dbCommand.ExecuteNonQuery())).Result;

                    result = logger?.CommandNonQueryExecuted(
                        dbCommand,
                        commandId,
                        connection.ConnectionId,
                        nonQueryResult,
                        startTime,
                        stopwatch.Elapsed)
                             ?? nonQueryResult;

                    break;

                case DbCommandMethod.ExecuteScalar:
                    var scalarResult = (logger?.CommandScalarExecuting(
                                            dbCommand,
                                            commandId,
                                            connection.ConnectionId,
                                            startTime: startTime)
                                        ?? new InterceptionResult <object>(dbCommand.ExecuteScalar())).Result;

                    result = logger?.CommandScalarExecuted(
                        dbCommand,
                        commandId,
                        connection.ConnectionId,
                        scalarResult,
                        startTime,
                        stopwatch.Elapsed)
                             ?? scalarResult;
                    break;

                case DbCommandMethod.ExecuteReader:
                    var reader = (logger?.CommandReaderExecuting(
                                      dbCommand,
                                      commandId,
                                      connection.ConnectionId,
                                      startTime: startTime)
                                  ?? new InterceptionResult <DbDataReader>(dbCommand.ExecuteReader())).Result;

                    if (logger != null)
                    {
                        reader = logger?.CommandReaderExecuted(
                            dbCommand,
                            commandId,
                            connection.ConnectionId,
                            reader,
                            startTime,
                            stopwatch.Elapsed);
                    }

                    result = new RelationalDataReader(
                        connection,
                        dbCommand,
                        reader,
                        commandId,
                        logger);

                    readerOpen = true;
                    break;

                default:
                    throw new NotSupportedException();
                }
            }
            catch (Exception exception)
            {
                logger?.CommandError(
                    dbCommand,
                    executeMethod,
                    commandId,
                    connection.ConnectionId,
                    exception,
                    false,
                    startTime,
                    stopwatch.Elapsed);

                throw;
            }
            finally
            {
                if (!readerOpen)
                {
                    dbCommand.Parameters.Clear();
                    dbCommand.Dispose();
                    connection.Close();
                }
            }

            return(result);
        }