/// <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); }
public TResult ExecuteComplex <TResult>(Action <DbCommand> initializer, Func <DbDataReader, TResult> materializer) { if (unbufferedReader != null) { unbufferedReader.Buffer(); unbufferedReader = null; } var result = default(object); var connection = CurrentDbContext.Context.Database.GetService <IRelationalConnection>(); connection.Open(); using (var command = CreateCommand(connection)) { initializer(command); var commandId = Guid.NewGuid(); var startTime = DateTimeOffset.UtcNow; var stopwatch = Stopwatch.StartNew(); logger.CommandExecuting( command, DbCommandMethod.ExecuteReader, commandId, connection.ConnectionId, false, startTime); try { using (var reader = command.ExecuteReader(CommandBehavior.CloseConnection)) { logger.CommandExecuted( command, DbCommandMethod.ExecuteReader, commandId, connection.ConnectionId, result, false, startTime, stopwatch.Elapsed); reader.Read(); CurrentDbContext.GetDependencies().StateManager.BeginTrackingQuery(); return(materializer(reader)); } } catch (Exception exception) { logger.CommandError( command, DbCommandMethod.ExecuteReader, commandId, connection.ConnectionId, exception, false, startTime, stopwatch.Elapsed); throw; } finally { connection.Close(); } } }
/// <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); }