예제 #1
0
        // <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);
            }
        }
예제 #2
0
        /// <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);
            }
        }