// <summary> // See comments in <see cref="UpdateCommand" />. // </summary> internal override async Task <long> ExecuteAsync( Dictionary <int, object> identifierValues, List <KeyValuePair <PropagatorResult, object> > generatedValues, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // Compile command using (var command = CreateCommand(identifierValues)) { var connection = Translator.Connection; // configure command to use the connection and transaction for this session command.Transaction = ((null == connection.CurrentTransaction) ? null : connection.CurrentTransaction.StoreTransaction); command.Connection = connection.StoreConnection; // FIX Klaus 12/09/2018: Prevents the previously assigned transaction from being deleted due to collateral effects during connection assignment. command.Transaction = command.Transaction ?? (connection.CurrentTransaction == null ? null : connection.CurrentTransaction.StoreTransaction); if (Translator.CommandTimeout.HasValue) { command.CommandTimeout = Translator.CommandTimeout.Value; } // Execute the query int rowsAffected; if (_modificationCommandTree.HasReader) { // retrieve server gen results rowsAffected = 0; using ( var reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken).WithCurrentCulture()) { if (await reader.ReadAsync(cancellationToken).WithCurrentCulture()) { rowsAffected++; var members = TypeHelpers.GetAllStructuralMembers(CurrentValues.StructuralType); for (var ordinal = 0; ordinal < reader.FieldCount; ordinal++) { // column name of result corresponds to column name of table var columnName = reader.GetName(ordinal); var member = members[columnName]; object value; if (Helper.IsSpatialType(member.TypeUsage) && !await reader.IsDBNullAsync(ordinal, cancellationToken).WithCurrentCulture()) { value = await SpatialHelpers.GetSpatialValueAsync( Translator.MetadataWorkspace, reader, member.TypeUsage, ordinal, cancellationToken). WithCurrentCulture(); } else { value = await reader.GetFieldValueAsync <object>(ordinal, cancellationToken).WithCurrentCulture(); } // retrieve result which includes the context for back-propagation var columnOrdinal = members.IndexOf(member); var result = CurrentValues.GetMemberValue(columnOrdinal); // register for back-propagation generatedValues.Add(new KeyValuePair <PropagatorResult, object>(result, value)); // register identifier if it exists var identifier = result.Identifier; if (PropagatorResult.NullIdentifier != identifier) { identifierValues.Add(identifier, value); } } } // Consume the current reader (and subsequent result sets) so that any errors // executing the command can be intercepted await CommandHelper.ConsumeReaderAsync(reader, cancellationToken).WithCurrentCulture(); } } else { rowsAffected = await command.ExecuteNonQueryAsync(cancellationToken).WithCurrentCulture(); } return(rowsAffected); } }
/// <summary> /// See comments in <see cref="UpdateCommand" />. /// </summary> internal override long Execute( Dictionary <int, object> identifierValues, List <KeyValuePair <PropagatorResult, object> > generatedValues, IDbCommandInterceptor commandInterceptor) { // Compile command using (var command = CreateCommand(identifierValues)) { var connection = Translator.Connection; // configure command to use the connection and transaction for this session command.Transaction = ((null == connection.CurrentTransaction) ? null : connection.CurrentTransaction.StoreTransaction); command.Connection = connection.StoreConnection; if (Translator.CommandTimeout.HasValue) { command.CommandTimeout = Translator.CommandTimeout.Value; } // Execute the query int rowsAffected; if (_modificationCommandTree.HasReader) { // retrieve server gen results rowsAffected = 0; using (var reader = command.ExecuteReader(CommandBehavior.SequentialAccess)) { if (reader.Read()) { rowsAffected++; var members = TypeHelpers.GetAllStructuralMembers(CurrentValues.StructuralType); for (var ordinal = 0; ordinal < reader.FieldCount; ordinal++) { // column name of result corresponds to column name of table var columnName = reader.GetName(ordinal); var member = members[columnName]; object value; if (Helper.IsSpatialType(member.TypeUsage) && !reader.IsDBNull(ordinal)) { value = SpatialHelpers.GetSpatialValue(Translator.MetadataWorkspace, reader, member.TypeUsage, ordinal); } else { value = reader.GetValue(ordinal); } // retrieve result which includes the context for back-propagation var columnOrdinal = members.IndexOf(member); var result = CurrentValues.GetMemberValue(columnOrdinal); // register for back-propagation generatedValues.Add(new KeyValuePair <PropagatorResult, object>(result, value)); // register identifier if it exists var identifier = result.Identifier; if (PropagatorResult.NullIdentifier != identifier) { identifierValues.Add(identifier, value); } } } // Consume the current reader (and subsequent result sets) so that any errors // executing the command can be intercepted CommandHelper.ConsumeReader(reader); } } else { // We currently only intercept commands on this code path. var executeCommand = true; if (commandInterceptor != null) { executeCommand = commandInterceptor.Intercept(command); } rowsAffected = executeCommand ? command.ExecuteNonQuery() : 1; } return(rowsAffected); } }