Exemplo n.º 1
0
    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public override ResultSetMapping AppendDeleteOperation(
        StringBuilder commandStringBuilder,
        IReadOnlyModificationCommand command,
        int commandPosition,
        out bool requiresTransaction)
    {
        // We normally do a simple DELETE, with an OUTPUT clause emitting "1" for concurrency checking.
        // However, if there are triggers defined, OUTPUT (without INTO) is not supported, so we do UPDATE+SELECT.
        if (!HasAnyTriggers(command))
        {
            return(base.AppendDeleteOperation(commandStringBuilder, command, commandPosition, out requiresTransaction));
        }

        var name       = command.TableName;
        var schema     = command.Schema;
        var operations = command.ColumnModifications;

        var conditionOperations = operations.Where(o => o.IsCondition).ToList();

        requiresTransaction = false;

        AppendDeleteCommand(commandStringBuilder, name, schema, Array.Empty <IColumnModification>(), conditionOperations);

        return(AppendSelectAffectedCountCommand(commandStringBuilder, name, schema, commandPosition));
    }
Exemplo n.º 2
0
        private void Format(IReadOnlyModificationCommand command, StringBuilder builder)
        {
            var entry      = command.Entries.First();
            var entityType = entry.EntityType;

            builder.Append(entityType.DisplayName());
            if (_sensitiveLoggingEnabled)
            {
                builder.Append(" { ");
                var properties = entityType.FindPrimaryKey() !.Properties;
                for (var i = 0; i < properties.Count; i++)
                {
                    var keyProperty = properties[i];
                    builder.Append('\'');
                    builder.Append(keyProperty.Name);
                    builder.Append("': ");
                    builder.Append(entry.GetCurrentValue(keyProperty));

                    if (i != properties.Count - 1)
                    {
                        builder.Append(", ");
                    }
                }

                builder.Append(" } ");
            }
            else
            {
                builder.Append(' ');
            }

            builder.Append('[');
            builder.Append(entry.EntityState);
            builder.Append(']');
        }
Exemplo n.º 3
0
    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public override ResultSetMapping AppendInsertOperation(
        StringBuilder commandStringBuilder,
        IReadOnlyModificationCommand command,
        int commandPosition,
        out bool requiresTransaction)
    {
        // If no database-generated columns need to be read back, just do a simple INSERT (default behavior).
        // If there are generated columns but there are no triggers defined on the table, we can do a simple INSERT ... OUTPUT
        // (without INTO), which is also the default behavior, doesn't require a transaction and is the most efficient.
        if (command.ColumnModifications.All(o => !o.IsRead) || !HasAnyTriggers(command))
        {
            return(base.AppendInsertOperation(commandStringBuilder, command, commandPosition, out requiresTransaction));
        }

        // SQL Server doesn't allow INSERT ... OUTPUT on tables with triggers.
        // If the only generated column is an IDENTITY, do INSERT+SELECT which is relatively fast.
        // Otherwise fall back to INSERT ... OUTPUT INTO @inserted; SELECT ... FROM @inserted.
        var table = StoreObjectIdentifier.Table(command.TableName, command.Schema);

        return(command.ColumnModifications.All(
                   o =>
                   !o.IsKey ||
                   !o.IsRead ||
                   o.Property?.GetValueGenerationStrategy(table) == SqlServerValueGenerationStrategy.IdentityColumn)
            ? AppendInsertAndSelectOperations(commandStringBuilder, command, commandPosition, out requiresTransaction)
            : AppendInsertSingleRowWithOutputInto(
                   commandStringBuilder,
                   command,
                   command.ColumnModifications.Where(o => o.IsKey).ToList(),
                   command.ColumnModifications.Where(o => o.IsRead).ToList(),
                   commandPosition,
                   out requiresTransaction));
    }
Exemplo n.º 4
0
    public override ResultSetMapping AppendUpdateOperation(
        StringBuilder commandStringBuilder,
        IReadOnlyModificationCommand command,
        int commandPosition)
    {
        Check.NotNull(commandStringBuilder, nameof(commandStringBuilder));
        Check.NotNull(command, nameof(command));

        var tableName  = command.TableName;
        var schemaName = command.Schema;
        var operations = command.ColumnModifications;

        var writeOperations     = operations.Where(o => o.IsWrite).ToArray();
        var conditionOperations = operations.Where(o => o.IsCondition).ToArray();
        var readOperations      = operations.Where(o => o.IsRead).ToArray();

        AppendUpdateCommandHeader(commandStringBuilder, tableName, schemaName, writeOperations);
        AppendWhereClause(commandStringBuilder, conditionOperations);
        if (readOperations.Length > 0)
        {
            AppendReturningClause(commandStringBuilder, readOperations);
        }
        commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator).AppendLine();
        return(ResultSetMapping.NoResultSet);
    }
Exemplo n.º 5
0
    public virtual ResultSetMapping AppendInsertOperation(
        StringBuilder commandStringBuilder,
        IReadOnlyModificationCommand command,
        int commandPosition,
        bool overridingSystemValue)
    {
        Check.NotNull(commandStringBuilder, nameof(commandStringBuilder));
        Check.NotNull(command, nameof(command));

        var name       = command.TableName;
        var schema     = command.Schema;
        var operations = command.ColumnModifications;

        var writeOperations = operations.Where(o => o.IsWrite).ToArray();
        var readOperations  = operations.Where(o => o.IsRead).ToArray();

        AppendInsertCommandHeader(commandStringBuilder, command.TableName, command.Schema, writeOperations);
        if (overridingSystemValue)
        {
            commandStringBuilder.AppendLine().Append("OVERRIDING SYSTEM VALUE");
        }

        AppendValuesHeader(commandStringBuilder, writeOperations);
        AppendValues(commandStringBuilder, name, schema, writeOperations);
        if (readOperations.Length > 0)
        {
            AppendReturningClause(commandStringBuilder, readOperations);
        }

        commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator).AppendLine();

        return(ResultSetMapping.NoResultSet);
    }
Exemplo n.º 6
0
        /// <summary>
        ///     Appends a SQL command for updating a row to the commands being built.
        /// </summary>
        /// <param name="commandStringBuilder"> The builder to which the SQL should be appended. </param>
        /// <param name="command"> The command that represents the delete operation. </param>
        /// <param name="commandPosition"> The ordinal of this command in the batch. </param>
        /// <returns> The <see cref="ResultSetMapping" /> for the command. </returns>
        public virtual ResultSetMapping AppendUpdateOperation(
            StringBuilder commandStringBuilder,
            IReadOnlyModificationCommand command,
            int commandPosition)
        {
            Check.NotNull(commandStringBuilder, nameof(commandStringBuilder));
            Check.NotNull(command, nameof(command));

            var name       = command.TableName;
            var schema     = command.Schema;
            var operations = command.ColumnModifications;

            var writeOperations     = operations.Where(o => o.IsWrite).ToList();
            var conditionOperations = operations.Where(o => o.IsCondition).ToList();
            var readOperations      = operations.Where(o => o.IsRead).ToList();

            AppendUpdateCommand(commandStringBuilder, name, schema, writeOperations, conditionOperations);

            if (readOperations.Count > 0)
            {
                var keyOperations = operations.Where(o => o.IsKey).ToList();

                return(AppendSelectAffectedCommand(commandStringBuilder, name, schema, readOperations, keyOperations, commandPosition));
            }

            return(AppendSelectAffectedCountCommand(commandStringBuilder, name, schema, commandPosition));
        }
Exemplo n.º 7
0
 public override ResultSetMapping AppendDeleteOperation(
     StringBuilder commandStringBuilder,
     IReadOnlyModificationCommand command,
     int commandPosition)
 {
     AppendDeleteOperationCalls++;
     return(base.AppendDeleteOperation(commandStringBuilder, command, commandPosition));
 }
Exemplo n.º 8
0
 public override ResultSetMapping AppendUpdateOperation(
     StringBuilder commandStringBuilder,
     IReadOnlyModificationCommand command,
     int commandPosition,
     out bool requiresTransaction)
 {
     AppendUpdateOperationCalls++;
     return(base.AppendUpdateOperation(commandStringBuilder, command, commandPosition, out requiresTransaction));
 }
Exemplo n.º 9
0
        private ModificationCommandBatch StartNewBatch(
            ParameterNameGenerator parameterNameGenerator,
            IReadOnlyModificationCommand modificationCommand)
        {
            parameterNameGenerator.Reset();
            var batch = Dependencies.ModificationCommandBatchFactory.Create();

            batch.AddCommand(modificationCommand);
            return(batch);
        }
Exemplo n.º 10
0
    /// <summary>
    ///     Appends a SQL command for deleting a row to the commands being built.
    /// </summary>
    /// <param name="commandStringBuilder">The builder to which the SQL should be appended.</param>
    /// <param name="command">The command that represents the delete operation.</param>
    /// <param name="commandPosition">The ordinal of this command in the batch.</param>
    /// <returns>The <see cref="ResultSetMapping" /> for the command.</returns>
    public virtual ResultSetMapping AppendDeleteOperation(
        StringBuilder commandStringBuilder,
        IReadOnlyModificationCommand command,
        int commandPosition)
    {
        var name   = command.TableName;
        var schema = command.Schema;
        var conditionOperations = command.ColumnModifications.Where(o => o.IsCondition).ToList();

        AppendDeleteCommand(commandStringBuilder, name, schema, conditionOperations);

        return(AppendSelectAffectedCountCommand(commandStringBuilder, name, schema, commandPosition));
    }
    protected override bool CanAddCommand(IReadOnlyModificationCommand modificationCommand)
    {
        if (ModificationCommands.Count >= _maxBatchSize)
        {
            return(false);
        }

        var newParamCount = (long)_parameterCount + modificationCommand.ColumnModifications.Count;

        if (newParamCount > int.MaxValue)
        {
            return(false);
        }

        _parameterCount = (int)newParamCount;
        return(true);
    }
Exemplo n.º 12
0
    /// <summary>
    ///     Appends a SQL command for deleting a row to the commands being built.
    /// </summary>
    /// <param name="commandStringBuilder">The builder to which the SQL should be appended.</param>
    /// <param name="command">The command that represents the delete operation.</param>
    /// <param name="commandPosition">The ordinal of this command in the batch.</param>
    /// <param name="requiresTransaction">Returns whether the SQL appended must be executed in a transaction to work correctly.</param>
    /// <returns>The <see cref="ResultSetMapping" /> for the command.</returns>
    public virtual ResultSetMapping AppendDeleteOperation(
        StringBuilder commandStringBuilder,
        IReadOnlyModificationCommand command,
        int commandPosition,
        out bool requiresTransaction)
    {
        var name   = command.TableName;
        var schema = command.Schema;
        var conditionOperations = command.ColumnModifications.Where(o => o.IsCondition).ToList();

        requiresTransaction = false;

        AppendDeleteCommand(
            commandStringBuilder, name, schema, Array.Empty <IColumnModification>(), conditionOperations, additionalReadValues: "1");

        return(ResultSetMapping.LastInResultSet);
    }
Exemplo n.º 13
0
        public override bool AddCommand(IReadOnlyModificationCommand modificationCommand)
        {
            if (_sqlServerBulkConfiguration.Disabled)
            {
                _bulkMode = false;
                return(_modificationCommandBatch.AddCommand(modificationCommand));
            }

            var state    = modificationCommand.EntityState;
            var bulkMode = false;

            if ((state == EntityState.Added && _bulkOptions.InsertEnabled) ||
                (state == EntityState.Deleted && _bulkOptions.DeleteEnabled))
            {
                bulkMode = true;
            }

            if (!_state.HasValue)
            {
                _state  = state;
                _table  = modificationCommand.TableName;
                _schema = modificationCommand.Schema;

                _bulkMode = bulkMode;
            }

            if (bulkMode != _bulkMode)
            {
                return(false);
            }

            if (!_bulkMode)
            {
                return(_modificationCommandBatch.AddCommand(modificationCommand));
            }

            if (_state != modificationCommand.EntityState || _table != modificationCommand.TableName || _schema != modificationCommand.Schema)
            {
                return(false);
            }

            _commands = _commands.Add(modificationCommand);

            return(true);
        }
Exemplo n.º 14
0
    public override ResultSetMapping AppendDeleteOperation(
        StringBuilder commandStringBuilder,
        IReadOnlyModificationCommand command,
        int commandPosition,
        out bool requiresTransaction)
    {
        // The default implementation adds RETURNING 1 to do concurrency check (was the row actually deleted), but in PostgreSQL we check
        // the per-statement row-affected value exposed by Npgsql in the batch; so no need for RETURNING 1.
        var name   = command.TableName;
        var schema = command.Schema;
        var conditionOperations = command.ColumnModifications.Where(o => o.IsCondition).ToList();

        requiresTransaction = false;

        AppendDeleteCommand(commandStringBuilder, name, schema, Array.Empty <IColumnModification>(), conditionOperations);

        return(ResultSetMapping.NoResultSet);
    }
Exemplo n.º 15
0
        private void Format(IIndex index, IReadOnlyModificationCommand source, IReadOnlyModificationCommand target, StringBuilder builder)
        {
            var reverseDependency = source.EntityState != EntityState.Deleted;

            if (reverseDependency)
            {
                builder.AppendLine(" <-");
            }
            else
            {
                builder.Append(' ');
            }

            builder.Append("Index ");

            var dependentCommand = reverseDependency ? target : source;
            var dependentEntry   = dependentCommand.Entries.First(e => index.DeclaringEntityType.IsAssignableFrom(e.EntityType));

            builder.Append("{ ");
            for (var i = 0; i < index.Properties.Count; i++)
            {
                var property = index.Properties[i];
                builder.Append('\'');
                builder.Append(property.Name);
                builder.Append('\'');
                if (_sensitiveLoggingEnabled)
                {
                    builder.Append(": ");
                    builder.Append(dependentEntry.GetCurrentValue(property));
                }

                if (i != index.Properties.Count - 1)
                {
                    builder.Append(", ");
                }
            }

            builder.Append(" } ");

            if (!reverseDependency)
            {
                builder.AppendLine("<-");
            }
        }
Exemplo n.º 16
0
    /// <summary>
    ///     Appends a SQL command for inserting a row to the commands being built.
    /// </summary>
    /// <param name="commandStringBuilder">The builder to which the SQL should be appended.</param>
    /// <param name="command">The command that represents the delete operation.</param>
    /// <param name="commandPosition">The ordinal of this command in the batch.</param>
    /// <param name="requiresTransaction">Returns whether the SQL appended must be executed in a transaction to work correctly.</param>
    /// <returns>The <see cref="ResultSetMapping" /> for the command.</returns>
    public virtual ResultSetMapping AppendInsertOperation(
        StringBuilder commandStringBuilder,
        IReadOnlyModificationCommand command,
        int commandPosition,
        out bool requiresTransaction)
    {
        var name       = command.TableName;
        var schema     = command.Schema;
        var operations = command.ColumnModifications;

        var writeOperations = operations.Where(o => o.IsWrite).ToList();
        var readOperations  = operations.Where(o => o.IsRead).ToList();

        AppendInsertCommand(commandStringBuilder, name, schema, writeOperations, readOperations);

        requiresTransaction = false;

        return(readOperations.Count > 0 ? ResultSetMapping.LastInResultSet : ResultSetMapping.NoResultSet);
    }
Exemplo n.º 17
0
 private static void AddMatchingPredecessorEdge <T>(
     Dictionary <T, List <IReadOnlyModificationCommand> > predecessorsMap,
     T keyValue,
     Multigraph <IReadOnlyModificationCommand, IAnnotatable> commandGraph,
     IReadOnlyModificationCommand command,
     IAnnotatable edge)
     where T : notnull
 {
     if (predecessorsMap.TryGetValue(keyValue, out var predecessorCommands))
     {
         foreach (var predecessor in predecessorCommands)
         {
             if (predecessor != command)
             {
                 commandGraph.AddEdge(predecessor, command, edge);
             }
         }
     }
 }
Exemplo n.º 18
0
    /// <summary>
    ///     Appends a SQL command for updating a row to the commands being built.
    /// </summary>
    /// <param name="commandStringBuilder">The builder to which the SQL should be appended.</param>
    /// <param name="command">The command that represents the delete operation.</param>
    /// <param name="commandPosition">The ordinal of this command in the batch.</param>
    /// <param name="requiresTransaction">Returns whether the SQL appended must be executed in a transaction to work correctly.</param>
    /// <returns>The <see cref="ResultSetMapping" /> for the command.</returns>
    public virtual ResultSetMapping AppendUpdateOperation(
        StringBuilder commandStringBuilder,
        IReadOnlyModificationCommand command,
        int commandPosition,
        out bool requiresTransaction)
    {
        var name       = command.TableName;
        var schema     = command.Schema;
        var operations = command.ColumnModifications;

        var writeOperations     = operations.Where(o => o.IsWrite).ToList();
        var conditionOperations = operations.Where(o => o.IsCondition).ToList();
        var readOperations      = operations.Where(o => o.IsRead).ToList();

        requiresTransaction = false;

        AppendUpdateCommand(
            commandStringBuilder, name, schema, writeOperations, readOperations, conditionOperations,
            additionalReadValues: readOperations.Count == 0 ? "1" : null);

        return(ResultSetMapping.LastInResultSet);
    }
Exemplo n.º 19
0
    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    protected virtual ResultSetMapping AppendInsertAndSelectOperations(
        StringBuilder commandStringBuilder,
        IReadOnlyModificationCommand command,
        int commandPosition,
        out bool requiresTransaction)
    {
        var name       = command.TableName;
        var schema     = command.Schema;
        var operations = command.ColumnModifications;

        var writeOperations = operations.Where(o => o.IsWrite).ToList();
        var readOperations  = operations.Where(o => o.IsRead).ToList();
        var keyOperations   = operations.Where(o => o.IsKey).ToList();

        Check.DebugAssert(readOperations.Count > 0, "AppendInsertAndSelectOperations called without any read operations");

        requiresTransaction = true;

        AppendInsertCommand(commandStringBuilder, name, schema, writeOperations, readOperations: Array.Empty <IColumnModification>());

        return(AppendSelectAffectedCommand(commandStringBuilder, name, schema, readOperations, keyOperations, commandPosition));
    }
Exemplo n.º 20
0
    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public override ResultSetMapping AppendUpdateOperation(
        StringBuilder commandStringBuilder,
        IReadOnlyModificationCommand command,
        int commandPosition,
        out bool requiresTransaction)
    {
        // We normally do a simple UPDATE with an OUTPUT clause (either for the generated columns, or for "1" for concurrency checking).
        // However, if there are triggers defined, OUTPUT (without INTO) is not supported, so we do UPDATE+SELECT.
        if (!HasAnyTriggers(command))
        {
            return(base.AppendUpdateOperation(commandStringBuilder, command, commandPosition, out requiresTransaction));
        }

        var name       = command.TableName;
        var schema     = command.Schema;
        var operations = command.ColumnModifications;

        var writeOperations     = operations.Where(o => o.IsWrite).ToList();
        var conditionOperations = operations.Where(o => o.IsCondition).ToList();
        var readOperations      = operations.Where(o => o.IsRead).ToList();

        AppendUpdateCommand(commandStringBuilder, name, schema, writeOperations, Array.Empty <IColumnModification>(), conditionOperations);

        if (readOperations.Count > 0)
        {
            var keyOperations = operations.Where(o => o.IsKey).ToList();

            requiresTransaction = true;

            return(AppendSelectAffectedCommand(commandStringBuilder, name, schema, readOperations, keyOperations, commandPosition));
        }

        requiresTransaction = false;

        return(AppendSelectAffectedCountCommand(commandStringBuilder, name, schema, commandPosition));
    }
    public override ResultSetMapping AppendUpdateOperation(StringBuilder commandStringBuilder, IReadOnlyModificationCommand command, int commandPosition)
    {
        var name                = command.TableName;
        var operations          = command.ColumnModifications;
        var writeOperations     = operations.Where(o => o.IsWrite).ToList();
        var readOperations      = operations.Where(o => o.IsRead).ToList();
        var conditionOperations = operations.Where(o => o.IsCondition).ToList();
        var inputOperations     = GenerateParameters(operations.Where(o => o.IsWrite || o.IsCondition)).ToList();
        var anyRead             = readOperations.Any();

        commandStringBuilder.Append("EXECUTE BLOCK (");
        commandStringBuilder.AppendJoin(inputOperations, (b, p) =>
        {
            b.Append(p.name);
            b.Append(" ");
            b.Append(p.type);
            b.Append(" = ?");
        }, ", ");
        commandStringBuilder.AppendLine(")");
        commandStringBuilder.Append("RETURNS (");
        if (anyRead)
        {
            commandStringBuilder.AppendJoin(readOperations, (b, e) =>
            {
                var type = GetColumnType(e);
                b.Append(SqlGenerationHelper.DelimitIdentifier(e.ColumnName));
                b.Append(" ");
                b.Append(type);
            }, ", ");
        }
        else
        {
            commandStringBuilder.Append("ROWS_AFFECTED INT");
        }
        commandStringBuilder.AppendLine(")");
        commandStringBuilder.AppendLine("AS");
        commandStringBuilder.AppendLine("BEGIN");
        AppendUpdateCommandHeader(commandStringBuilder, name, null, writeOperations);
        AppendWhereClause(commandStringBuilder, conditionOperations);
        if (anyRead)
        {
            commandStringBuilder.AppendLine();
            commandStringBuilder.Append("RETURNING ");
            commandStringBuilder.AppendJoin(readOperations, (b, e) =>
            {
                b.Append(SqlGenerationHelper.DelimitIdentifier(e.ColumnName));
            }, ", ");
            commandStringBuilder.Append(" INTO ");
            commandStringBuilder.AppendJoin(readOperations, (b, e) =>
            {
                b.Append(":");
                b.Append(SqlGenerationHelper.DelimitIdentifier(e.ColumnName));
            }, ", ");
        }
        commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator).AppendLine();
        if (!anyRead)
        {
            commandStringBuilder.AppendLine("ROWS_AFFECTED = ROW_COUNT;");
            commandStringBuilder.AppendLine("SUSPEND;");
        }
        else
        {
            commandStringBuilder.AppendLine("IF (ROW_COUNT > 0) THEN");
            commandStringBuilder.AppendLine("SUSPEND;");
        }
        commandStringBuilder.Append("END");
        commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator).AppendLine();
        return(ResultSetMapping.LastInResultSet);
    }
Exemplo n.º 22
0
 protected override bool CanAddCommand(IReadOnlyModificationCommand modificationCommand)
 => ModificationCommands.Count < _maxBatchSize;
Exemplo n.º 23
0
 /// <summary>
 ///     Adds the given insert/update/delete <see cref="ModificationCommands" /> to the batch.
 /// </summary>
 /// <param name="modificationCommand">The command to add.</param>
 /// <returns>
 ///     <see langword="true" /> if the command was successfully added; <see langword="false" /> if there was no
 ///     room in the current batch to add the command and it must instead be added to a new batch.
 /// </returns>
 public abstract bool AddCommand(IReadOnlyModificationCommand modificationCommand);
 /// <summary>
 ///     Only returns <see langword="true" /> if the no command has already been added.
 /// </summary>
 /// <param name="modificationCommand">The command to potentially add.</param>
 /// <returns><see langword="true" /> if no command has already been added.</returns>
 protected override bool CanAddCommand(IReadOnlyModificationCommand modificationCommand)
 => ModificationCommands.Count == 0;
Exemplo n.º 25
0
        private void Format(IForeignKey foreignKey, IReadOnlyModificationCommand source, IReadOnlyModificationCommand target, StringBuilder builder)
        {
            var reverseDependency = !source.Entries.Any(e => foreignKey.DeclaringEntityType.IsAssignableFrom(e.EntityType));

            if (reverseDependency)
            {
                builder.AppendLine(" <-");
            }
            else
            {
                builder.Append(' ');
            }

            if (foreignKey.DependentToPrincipal != null ||
                foreignKey.PrincipalToDependent != null)
            {
                if (!reverseDependency &&
                    foreignKey.DependentToPrincipal != null)
                {
                    builder.Append(foreignKey.DependentToPrincipal.Name);
                    builder.Append(' ');
                }

                if (foreignKey.PrincipalToDependent != null)
                {
                    builder.Append(foreignKey.PrincipalToDependent.Name);
                    builder.Append(' ');
                }

                if (reverseDependency &&
                    foreignKey.DependentToPrincipal != null)
                {
                    builder.Append(foreignKey.DependentToPrincipal.Name);
                    builder.Append(' ');
                }
            }
            else
            {
                builder.Append("ForeignKey ");
            }

            var dependentCommand = reverseDependency ? target : source;
            var dependentEntry   = dependentCommand.Entries.First(e => foreignKey.DeclaringEntityType.IsAssignableFrom(e.EntityType));

            builder.Append("{ ");
            for (var i = 0; i < foreignKey.Properties.Count; i++)
            {
                var property = foreignKey.Properties[i];
                builder.Append('\'');
                builder.Append(property.Name);
                builder.Append('\'');
                if (_sensitiveLoggingEnabled)
                {
                    builder.Append(": ");
                    builder.Append(dependentEntry.GetCurrentValue(property));
                }

                if (i != foreignKey.Properties.Count - 1)
                {
                    builder.Append(", ");
                }
            }

            builder.Append(" } ");

            if (!reverseDependency)
            {
                builder.AppendLine("<-");
            }
        }
Exemplo n.º 26
0
 public override ResultSetMapping AppendInsertOperation(
     StringBuilder commandStringBuilder,
     IReadOnlyModificationCommand command,
     int commandPosition)
 => AppendInsertOperation(commandStringBuilder, command, commandPosition, false);
Exemplo n.º 27
0
 public override ResultSetMapping AppendInsertOperation(
     StringBuilder commandStringBuilder,
     IReadOnlyModificationCommand command,
     int commandPosition,
     out bool requiresTransaction)
 => AppendInsertOperation(commandStringBuilder, command, commandPosition, overridingSystemValue: false, out requiresTransaction);
    public override ResultSetMapping AppendInsertOperation(StringBuilder commandStringBuilder, IReadOnlyModificationCommand command, int commandPosition)
    {
        var result          = ResultSetMapping.NoResultSet;
        var name            = command.TableName;
        var operations      = command.ColumnModifications;
        var writeOperations = operations.Where(o => o.IsWrite).ToList();
        var readOperations  = operations.Where(o => o.IsRead).ToList();
        var anyRead         = readOperations.Any();

        AppendInsertCommandHeader(commandStringBuilder, name, null, writeOperations);
        AppendValuesHeader(commandStringBuilder, writeOperations);
        AppendValues(commandStringBuilder, name, null, writeOperations);
        if (anyRead)
        {
            commandStringBuilder.AppendLine();
            commandStringBuilder.Append("RETURNING ");
            commandStringBuilder.AppendJoin(readOperations, (b, e) =>
            {
                b.Append(SqlGenerationHelper.DelimitIdentifier(e.ColumnName));
            }, ", ");
            result = ResultSetMapping.LastInResultSet;
        }
        commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator).AppendLine();
        return(result);
    }
    public override ResultSetMapping AppendDeleteOperation(StringBuilder commandStringBuilder, IReadOnlyModificationCommand command, int commandPosition)
    {
        var name                = command.TableName;
        var operations          = command.ColumnModifications;
        var conditionOperations = operations.Where(o => o.IsCondition).ToList();
        var inputOperations     = GenerateParameters(conditionOperations);

        commandStringBuilder.Append("EXECUTE BLOCK (");
        commandStringBuilder.AppendJoin(inputOperations, (b, p) =>
        {
            b.Append(p.name);
            b.Append(" ");
            b.Append(p.type);
            b.Append(" = ?");
        }, ", ");
        commandStringBuilder.AppendLine(")");
        commandStringBuilder.AppendLine("RETURNS (ROWS_AFFECTED INT)");
        commandStringBuilder.AppendLine("AS");
        commandStringBuilder.AppendLine("BEGIN");
        AppendDeleteCommandHeader(commandStringBuilder, name, null);
        AppendWhereClause(commandStringBuilder, conditionOperations);
        commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator).AppendLine();
        commandStringBuilder.AppendLine();
        commandStringBuilder.AppendLine("ROWS_AFFECTED = ROW_COUNT;");
        commandStringBuilder.AppendLine("SUSPEND;");
        commandStringBuilder.Append("END");
        commandStringBuilder.Append(SqlGenerationHelper.StatementTerminator).AppendLine();
        return(ResultSetMapping.LastInResultSet);
    }
 protected override bool CanAddCommand(IReadOnlyModificationCommand modificationCommand)
 => ShouldAddCommand;