コード例 #1
0
        protected override Expression VisitInsertInto(SqlInsertIntoExpression insertIntoExpression)
        {
            var projection = insertIntoExpression.Source as SqlProjectionExpression;

            if (projection == null)
            {
                return(insertIntoExpression);
            }

            if (projection.Select.From.NodeType != (ExpressionType)SqlExpressionType.Table)
            {
                throw new NotSupportedException();
            }

            var table = (SqlTableExpression)projection.Select.From;
            var alias = table.Alias;

            var where = AliasReferenceReplacer.Replace(projection.Select.Where, alias, table.Name);

            if (where != null)
            {
                throw new InvalidOperationException("Inserts must only be performed on pure tables");
            }

            return(new SqlInsertIntoExpression(table, insertIntoExpression.ColumnNames, insertIntoExpression.ReturningAutoIncrementColumnNames, insertIntoExpression.ValueExpressions));
        }
コード例 #2
0
        protected override Expression VisitUpdate(SqlUpdateExpression expression)
        {
            if (!expression.RequiresIdentityInsert)
            {
                return(base.VisitUpdate(expression));
            }

            var tableName = ((SqlTableExpression)expression.Source).Name;

            var typeDescriptor = this
                                 .typeDescriptorProvider
                                 .GetTypeDescriptors()
                                 .Single(c => c.PersistedName == tableName);

            var insertedColumns = expression
                                  .Assignments
                                  .OfType <SqlAssignExpression>()
                                  .Select(c => new { name = ((SqlColumnExpression)c.Target).Name, value = c.Value, propertyDescriptor = typeDescriptor.GetPropertyDescriptorByColumnName(((SqlColumnExpression)c.Target).Name) })
                                  .ToList();

            var columnInfos = QueryBinder
                              .GetColumnInfos(this.typeDescriptorProvider, typeDescriptor.PersistedProperties.Where(c => insertedColumns.All(d => d.propertyDescriptor != c)))
                              .ToList();

            var visitedUpdated       = (SqlUpdateExpression)base.VisitUpdate(expression);
            var selectIntoExpression = new SqlSelectExpression
                                       (
                typeof(void),
                null,
                columnInfos.Select
                (
                    c => new SqlColumnDeclaration
                    (
                        null, new SqlColumnExpression(c.DefinitionProperty.PropertyType, null, c.GetColumnName())
                    )
                )
                .Concat(insertedColumns.Select(d => d.value.Type.GetUnwrappedNullableType() == typeof(bool) ? new SqlColumnDeclaration(d.name, new BitBooleanExpression(d.value)) : new SqlColumnDeclaration(d.name, d.value)))
                .ToReadOnlyCollection(),
                visitedUpdated.Source,
                visitedUpdated.Where,
                null, null, false, null, null, false, false, new SqlTableExpression("#TEMP")
                                       );

            var selectExpression = new SqlSelectExpression(typeof(void), null, null, selectIntoExpression.Into, null, null);
            var insertExpression = new SqlInsertIntoExpression(visitedUpdated.Source, columnInfos.Select(c => c.GetColumnName()).Concat(insertedColumns.Select(c => c.name)).ToReadOnlyCollection(), null, selectExpression, null, true);
            var deleteExpression = new SqlDeleteExpression(visitedUpdated.Source, visitedUpdated.Where);

            var list = new List <Expression>
            {
                selectIntoExpression,
                deleteExpression,
                new SqlSetCommandExpression("IDENTITY_INSERT", visitedUpdated.Source, new SqlKeywordExpression("ON")),
                insertExpression,
                new SqlSetCommandExpression("IDENTITY_INSERT", visitedUpdated.Source, new SqlKeywordExpression("OFF")),
            };

            return(new SqlStatementListExpression(list));
        }
コード例 #3
0
        protected virtual IDbCommand BuildInsertCommand(TypeDescriptor typeDescriptor, DataAccessObject dataAccessObject)
        {
            IDbCommand      command;
            SqlCommandValue sqlCommandValue;

            var updatedProperties = dataAccessObject.GetAdvanced().GetChangedPropertiesFlattened();
            var commandKey        = new SqlCommandKey(dataAccessObject.GetType(), updatedProperties);

            if (this.TryGetInsertCommand(commandKey, out sqlCommandValue))
            {
                command             = this.CreateCommand();
                command.CommandText = sqlCommandValue.commandText;
                this.FillParameters(command, updatedProperties, null);

                return(command);
            }

            IReadOnlyList <string> returningAutoIncrementColumnNames = null;

            if (dataAccessObject.GetAdvanced().DefinesAnyDirectPropertiesGeneratedOnTheServerSide)
            {
                var propertyDescriptors = typeDescriptor.PersistedProperties.Where(c => c.IsPropertyThatIsCreatedOnTheServerSide).ToList();

                returningAutoIncrementColumnNames = new ReadOnlyList <string>(propertyDescriptors.Select(c => c.PersistedName).ToList());
            }

            var        columnNames      = new ReadOnlyList <string>(updatedProperties.Select(c => c.PersistedName).ToList());
            var        valueExpressions = new ReadOnlyList <Expression>(updatedProperties.Select(c => (Expression)Expression.Constant(c.Value)).ToList());
            Expression expression       = new SqlInsertIntoExpression(new SqlTableExpression(typeDescriptor.PersistedName), columnNames, returningAutoIncrementColumnNames, valueExpressions);

            if (this.SqlDatabaseContext.SqlDialect.SupportsFeature(SqlFeature.PragmaIdentityInsert) && dataAccessObject.ToObjectInternal().HasAnyChangedPrimaryKeyServerSideProperties)
            {
                var list = new List <Expression>
                {
                    new SqlSetCommandExpression("IdentityInsert", new SqlTableExpression(typeDescriptor.PersistedName), Expression.Constant(true)),
                    expression,
                    new SqlSetCommandExpression("IdentityInsert", new SqlTableExpression(typeDescriptor.PersistedName), Expression.Constant(false)),
                };

                expression = new SqlStatementListExpression(list);
            }

            var result = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(expression, SqlQueryFormatterOptions.Default & ~SqlQueryFormatterOptions.OptimiseOutConstantNulls);

            Debug.Assert(result.ParameterValues.Count() == updatedProperties.Count);

            command = this.CreateCommand();

            var commandText = result.CommandText;

            command.CommandText = commandText;
            this.CacheInsertCommand(commandKey, new SqlCommandValue {
                commandText = command.CommandText
            });
            this.FillParameters(command, updatedProperties, null);

            return(command);
        }
コード例 #4
0
        protected override void WriteInsertIntoReturning(SqlInsertIntoExpression expression)
        {
            if (expression.ReturningAutoIncrementColumnNames == null ||
                expression.ReturningAutoIncrementColumnNames.Count == 0)
            {
                return;
            }

            this.Write("; SELECT last_insert_rowid()");
        }
コード例 #5
0
        protected override void WriteInsertIntoReturning(SqlInsertIntoExpression expression)
        {
            if (expression.ReturningAutoIncrementColumnNames == null ||
                expression.ReturningAutoIncrementColumnNames.Count == 0)
            {
                return;
            }

            Write("; SELECT LAST_INSERT_ID()");
        }
コード例 #6
0
        protected override void WriteInsertIntoReturning(SqlInsertIntoExpression expression)
        {
            if (expression.ReturningAutoIncrementColumnNames == null ||
                expression.ReturningAutoIncrementColumnNames.Count == 0)
            {
                return;
            }

            this.Write(" RETURNING ");
            this.WriteDeliminatedListOfItems <string>(expression.ReturningAutoIncrementColumnNames, this.WriteQuotedIdentifier, ",");
        }
コード例 #7
0
        protected override bool WriteInsertIntoAfterSource(SqlInsertIntoExpression expression)
        {
            var tableHintExpression = expression.WithExpression as SqlTableHintExpression;

            if (tableHintExpression?.TableLock == true)
            {
                Write(" WITH (TABLOCK) ");
            }

            return(true);
        }
コード例 #8
0
        protected virtual Expression VisitInsertInto(SqlInsertIntoExpression expression)
        {
            var source           = this.VisitSource(expression.Source);
            var valueExpressions = this.VisitExpressionList(expression.ValueExpressions);

            if (source != expression.Source || valueExpressions != expression.ValueExpressions)
            {
                return(new SqlInsertIntoExpression(source, expression.ColumnNames, expression.ReturningAutoIncrementColumnNames, valueExpressions));
            }

            return(expression);
        }
コード例 #9
0
        protected override Expression VisitInsertInto(SqlInsertIntoExpression expression)
        {
            if (!expression.RequiresIdentityInsert)
            {
                return(base.VisitInsertInto(expression));
            }

            var list = new List <Expression>
            {
                new SqlSetCommandExpression("IDENTITY_INSERT", expression.Source, new SqlKeywordExpression("ON")),
                base.VisitInsertInto(expression),
                new SqlSetCommandExpression("IDENTITY_INSERT", expression.Source, new SqlKeywordExpression("OFF")),
            };

            return(new SqlStatementListExpression(list));
        }
コード例 #10
0
        protected override void WriteInsertIntoReturning(SqlInsertIntoExpression expression)
        {
            if (expression.ReturningAutoIncrementColumnNames == null ||
                expression.ReturningAutoIncrementColumnNames.Count == 0)
            {
                return;
            }

            Write(" OUTPUT ");
            WriteDeliminatedListOfItems <string>(expression.ReturningAutoIncrementColumnNames, c =>
            {
                WriteQuotedIdentifier("INSERTED");
                Write(".");
                WriteQuotedIdentifier(c);
            }, ",");
            Write("");
        }
コード例 #11
0
        protected override Expression VisitInsertInto(SqlInsertIntoExpression expression)
        {
            if (expression.ReturningAutoIncrementColumnNames != null && expression.ReturningAutoIncrementColumnNames.Count == 1)
            {
                var returningColumnName = expression.ReturningAutoIncrementColumnNames[0];
                var index = expression.ColumnNames.IndexOf(returningColumnName);

                if (index > 0)
                {
                    var newValueExpressions = new List <Expression>(expression.ValueExpressions);

                    newValueExpressions[index] = new SqlFunctionCallExpression(newValueExpressions[index].Type, "LAST_INSERT_ID", newValueExpressions[index]);

                    return(new SqlInsertIntoExpression(expression.Source, expression.ColumnNames, expression.ReturningAutoIncrementColumnNames, newValueExpressions));
                }
            }

            return(expression);
        }
コード例 #12
0
ファイル: Sql92QueryFormatter.cs プロジェクト: ciker/Shaolinq
        protected override Expression VisitInsertInto(SqlInsertIntoExpression expression)
        {
            this.Write("INSERT INTO ");
            this.Visit(expression.Table);

            if (expression.ValueExpressions == null || expression.ValueExpressions.Count == 0)
            {
                this.WriteInsertDefaultValuesSuffix();
            }
            else
            {
                this.Write("(");
                this.WriteDeliminatedListOfItems(expression.ColumnNames, this.WriteQuotedIdentifier);

                this.Write(") ");

                if (this.sqlDialect.SupportsFeature(SqlFeature.InsertOutput))
                {
                    this.WriteInsertIntoReturning(expression);
                    this.Write(" ");
                }

                this.Write("VALUES (");
                this.WriteDeliminatedListOfItems(expression.ValueExpressions, c => this.Visit(c));
                this.Write(")");
            }

            if (!this.sqlDialect.SupportsFeature(SqlFeature.InsertOutput))
            {
                this.WriteInsertIntoReturning(expression);
            }

            this.Write(";");

            return(expression);
        }
コード例 #13
0
 protected override Expression VisitInsertInto(SqlInsertIntoExpression insertIntoExpression)
 {
     return(insertIntoExpression);
 }
コード例 #14
0
        protected virtual IDbCommand BuildInsertCommand(TypeDescriptor typeDescriptor, DataAccessObject dataAccessObject)
        {
            var        success = false;
            IDbCommand command = null;
            SqlCachedUpdateInsertFormatValue cachedValue;
            bool predicated;

            var requiresIdentityInsert = dataAccessObject.ToObjectInternal().HasAnyChangedPrimaryKeyServerSideProperties;

            var updatedProperties = dataAccessObject.ToObjectInternal().GetChangedPropertiesFlattened(out predicated);

            if (predicated)
            {
                return(BuildInsertCommandForDeflatedPredicated(typeDescriptor, dataAccessObject, updatedProperties));
            }

            var commandKey = new SqlCachedUpdateInsertFormatKey(dataAccessObject.GetType(), updatedProperties, requiresIdentityInsert);

            if (this.TryGetInsertCommand(commandKey, out cachedValue))
            {
                try
                {
                    command             = this.CreateCommand();
                    command.CommandText = cachedValue.formatResult.CommandText;
                    this.FillParameters(command, cachedValue, updatedProperties, null);

                    success = true;

                    return(command);
                }
                finally
                {
                    if (!success)
                    {
                        command?.Dispose();
                    }
                }
            }

            IReadOnlyList <string> returningAutoIncrementColumnNames = null;

            if (dataAccessObject.GetAdvanced().DefinesAnyDirectPropertiesGeneratedOnTheServerSide)
            {
                var propertyDescriptors = typeDescriptor.PersistedPropertiesWithoutBackreferences.Where(c => c.IsPropertyThatIsCreatedOnTheServerSide).ToList();

                returningAutoIncrementColumnNames = propertyDescriptors.Select(c => c.PersistedName).ToReadOnlyCollection();
            }

            var constantPlaceholdersCount = 0;
            var valueIndexesToParameterPlaceholderIndexes = new int[updatedProperties.Count];

            var columnNames = updatedProperties.Select(c => c.PersistedName).ToReadOnlyCollection();

            var valueExpressions = new List <Expression>(updatedProperties.Count);

            foreach (var updated in updatedProperties)
            {
                var value = (Expression) new SqlConstantPlaceholderExpression(constantPlaceholdersCount++, Expression.Constant(updated.Value, updated.PropertyType.CanBeNull() ? updated.PropertyType : updated.PropertyType.MakeNullable()));

                if (value.Type != updated.PropertyType)
                {
                    value = Expression.Convert(value, updated.PropertyType);
                }

                valueExpressions.Add(value);
            }

            Expression expression = new SqlInsertIntoExpression(new SqlTableExpression(typeDescriptor.PersistedName), columnNames, returningAutoIncrementColumnNames, valueExpressions, null, requiresIdentityInsert);

            for (var i = 0; i < constantPlaceholdersCount; i++)
            {
                valueIndexesToParameterPlaceholderIndexes[i] = i;
            }

            var result = this.SqlDatabaseContext.SqlQueryFormatterManager.Format(expression);

            try
            {
                command = this.CreateCommand();

                var commandText = result.CommandText;

                command.CommandText = commandText;
                cachedValue         = new SqlCachedUpdateInsertFormatValue {
                    formatResult = result, valueIndexesToParameterPlaceholderIndexes = valueIndexesToParameterPlaceholderIndexes, primaryKeyIndexesToParameterPlaceholderIndexes = null
                };

                if (result.Cacheable)
                {
                    this.CacheInsertCommand(commandKey, cachedValue);
                }

                this.FillParameters(command, cachedValue, updatedProperties, null);

                success = true;

                return(command);
            }
            finally
            {
                if (!success)
                {
                    command?.Dispose();
                }
            }
        }
コード例 #15
0
 protected virtual Expression VisitInsertInto(SqlInsertIntoExpression expression)
 {
     return(expression);
 }