Exemple #1
0
        internal static string GenerateDeleteSql(
            DbDeleteCommandTree tree,
            SqlGenerator sqlGenerator,
            out List <SqlParameter> parameters,
            bool upperCaseKeywords = true,
            bool createParameters  = true)
        {
            var commandText
                = new SqlStringBuilder(CommandTextBuilderInitialCapacity)
                {
                UpperCaseKeywords = upperCaseKeywords
                };

            var translator
                = new ExpressionTranslator(
                      commandText,
                      tree,
                      false,
                      sqlGenerator,
                      createParameters: createParameters);

            // delete [schemaName].[tableName]
            commandText.AppendKeyword("delete ");
            tree.Target.Expression.Accept(translator);
            commandText.AppendLine();

            // where c1 = ... AND c2 = ...
            commandText.AppendKeyword("where ");
            tree.Predicate.Accept(translator);

            parameters = translator.Parameters;
            return(commandText.ToString());
        }
Exemple #2
0
            public override void Visit(DbIsNullExpression expression)
            {
                Check.NotNull(expression, "expression");

                expression.Argument.Accept(this);
                _commandText.AppendKeyword(" is null");
            }
        internal static string GenerateUpdateSql(
            DbUpdateCommandTree tree,
            SqlGenerator sqlGenerator,
            out List <SqlParameter> parameters,
            bool generateReturningSql = true,
            bool upperCaseKeywords    = true)
        {
            SqlStringBuilder commandText = new SqlStringBuilder(256)
            {
                UpperCaseKeywords = upperCaseKeywords
            };

            DmlSqlGenerator.ExpressionTranslator translator = new DmlSqlGenerator.ExpressionTranslator(commandText, (DbModificationCommandTree)tree, null != tree.Returning, sqlGenerator, (ICollection <EdmProperty>)null, true);
            if (tree.SetClauses.Count == 0)
            {
                commandText.AppendKeyword("declare ");
                commandText.AppendLine("@p int");
            }
            commandText.AppendKeyword("update ");
            tree.Target.Expression.Accept((DbExpressionVisitor)translator);
            commandText.AppendLine();
            bool flag = true;

            commandText.AppendKeyword("set ");
            foreach (DbSetClause setClause in (IEnumerable <DbModificationClause>)tree.SetClauses)
            {
                if (flag)
                {
                    flag = false;
                }
                else
                {
                    commandText.Append(", ");
                }
                setClause.Property.Accept((DbExpressionVisitor)translator);
                commandText.Append(" = ");
                setClause.Value.Accept((DbExpressionVisitor)translator);
            }
            if (flag)
            {
                commandText.Append("@p = 0");
            }
            commandText.AppendLine();
            commandText.AppendKeyword("where ");
            tree.Predicate.Accept((DbExpressionVisitor)translator);
            commandText.AppendLine();
            if (generateReturningSql)
            {
                DmlSqlGenerator.GenerateReturningSql(commandText, (DbModificationCommandTree)tree, (EntityType)null, translator, tree.Returning, false);
            }
            parameters = translator.Parameters;
            return(commandText.ToString());
        }
Exemple #4
0
        public void AppendKeyWord_should_case_based_on_property()
        {
            var sqlStringBuilder = new SqlStringBuilder();

            sqlStringBuilder.AppendKeyword("select");

            Assert.Equal("select", sqlStringBuilder.ToString());

            sqlStringBuilder.UpperCaseKeywords = true;

            sqlStringBuilder.AppendKeyword(" from");

            Assert.Equal("select FROM", sqlStringBuilder.ToString());
        }
Exemple #5
0
        public void AppendKeyWord_should_case_based_on_property()
        {
            var sqlStringBuilder = new SqlStringBuilder();

            sqlStringBuilder.AppendKeyword("select");

            Assert.Equal("select", sqlStringBuilder.ToString());

            sqlStringBuilder.UpperCaseKeywords = true;

            sqlStringBuilder.AppendKeyword(" from");

            Assert.Equal("select FROM", sqlStringBuilder.ToString());
        }
        internal static string GenerateDeleteSql(
            DbDeleteCommandTree tree,
            SqlGenerator sqlGenerator,
            out List <SqlParameter> parameters,
            bool upperCaseKeywords = true,
            bool createParameters  = true)
        {
            SqlStringBuilder commandText = new SqlStringBuilder(256)
            {
                UpperCaseKeywords = upperCaseKeywords
            };

            DmlSqlGenerator.ExpressionTranslator expressionTranslator = new DmlSqlGenerator.ExpressionTranslator(commandText, (DbModificationCommandTree)tree, false, sqlGenerator, (ICollection <EdmProperty>)null, createParameters);
            commandText.AppendKeyword("delete ");
            tree.Target.Expression.Accept((DbExpressionVisitor)expressionTranslator);
            commandText.AppendLine();
            commandText.AppendKeyword("where ");
            tree.Predicate.Accept((DbExpressionVisitor)expressionTranslator);
            parameters = expressionTranslator.Parameters;
            return(commandText.ToString());
        }
Exemple #7
0
        /// <summary>
        ///     Generates SQL fragment returning server-generated values.
        ///     Requires: translator knows about member values so that we can figure out
        ///     how to construct the key predicate.
        ///     <code>Sample SQL:
        ///
        ///         select IdentityValue
        ///         from dbo.MyTable
        ///         where @@ROWCOUNT > 0 and IdentityValue = scope_identity()
        ///
        ///         or
        ///
        ///         select TimestampValue
        ///         from dbo.MyTable
        ///         where @@ROWCOUNT > 0 and Id = 1
        ///
        ///         Note that we filter on rowcount to ensure no rows are returned if no rows were modified.
        ///
        ///         On SQL Server 2005 and up, we have an additional syntax used for non integer return types:
        ///
        ///         declare @generatedValues table(ID uniqueidentifier)
        ///         insert dbo.MyTable
        ///         output ID into @generated_values
        ///         values (...);
        ///         select ID
        ///         from @generatedValues as g join dbo.MyTable as t on g.ID = t.ID
        ///         where @@ROWCOUNT > 0;</code>
        /// </summary>
        /// <param name="commandText"> Builder containing command text </param>
        /// <param name="tree"> Modification command tree </param>
        /// <param name="tableType"> Type of table. </param>
        /// <param name="translator"> Translator used to produce DML SQL statement for the tree </param>
        /// <param name="returning"> Returning expression. If null, the method returns immediately without producing a SELECT statement. </param>
        internal static void GenerateReturningSql(
            SqlStringBuilder commandText,
            DbModificationCommandTree tree,
            EntityType tableType,
            ExpressionTranslator translator,
            DbExpression returning,
            bool useGeneratedValuesVariable)
        {
            // Nothing to do if there is no Returning expression
            if (null == returning)
            {
                return;
            }

            // select
            commandText.AppendKeyword("select ");
            if (useGeneratedValuesVariable)
            {
                translator.PropertyAlias = "t";
            }
            returning.Accept(translator);
            if (useGeneratedValuesVariable)
            {
                translator.PropertyAlias = null;
            }
            commandText.AppendLine();

            if (useGeneratedValuesVariable)
            {
                // from @generated_keys
                commandText.AppendKeyword("from ");
                commandText.Append(GeneratedValuesVariableName);
                commandText.AppendKeyword(" as ");
                commandText.Append("g");
                commandText.AppendKeyword(" join ");
                tree.Target.Expression.Accept(translator);
                commandText.AppendKeyword(" as ");
                commandText.Append("t");
                commandText.AppendKeyword(" on ");
                var separator = string.Empty;
                foreach (var keyMember in tableType.KeyMembers)
                {
                    commandText.AppendKeyword(separator);
                    separator = " and ";
                    commandText.Append("g.");
                    var memberTSql = GenerateMemberTSql(keyMember);
                    commandText.Append(memberTSql);
                    commandText.Append(" = t.");
                    commandText.Append(memberTSql);
                }
                commandText.AppendLine();
                commandText.AppendKeyword("where @@ROWCOUNT > 0");
            }
            else
            {
                // from
                commandText.AppendKeyword("from ");
                tree.Target.Expression.Accept(translator);
                commandText.AppendLine();

                // where
                commandText.AppendKeyword("where @@ROWCOUNT > 0");
                var table    = ((DbScanExpression)tree.Target.Expression).Target;
                var identity = false;
                foreach (var keyMember in table.ElementType.KeyMembers)
                {
                    commandText.AppendKeyword(" and ");
                    commandText.Append(GenerateMemberTSql(keyMember));
                    commandText.Append(" = ");

                    // retrieve member value sql. the translator remembers member values
                    // as it constructs the DML statement (which precedes the "returning"
                    // SQL)
                    SqlParameter value;
                    if (translator.MemberValues.TryGetValue(keyMember, out value))
                    {
                        commandText.Append(value.ParameterName);
                    }
                    else
                    {
                        // if no value is registered for the key member, it means it is an identity
                        // which can be retrieved using the scope_identity() function
                        if (identity)
                        {
                            // there can be only one server generated key
                            throw new NotSupportedException(Strings.Update_NotSupportedServerGenKey(table.Name));
                        }

                        if (!IsValidScopeIdentityColumnType(keyMember.TypeUsage))
                        {
                            throw new InvalidOperationException(
                                      Strings.Update_NotSupportedIdentityType(
                                          keyMember.Name, keyMember.TypeUsage.ToString()));
                        }

                        commandText.Append("scope_identity()");
                        identity = true;
                    }
                }
            }
        }
Exemple #8
0
        internal static string GenerateUpdateSql(
            DbUpdateCommandTree tree,
            SqlGenerator sqlGenerator,
            out List <SqlParameter> parameters,
            bool generateReturningSql = true,
            bool upperCaseKeywords    = true)
        {
            const string dummySetParameter = "@p";

            var commandText
                = new SqlStringBuilder(CommandTextBuilderInitialCapacity)
                {
                UpperCaseKeywords = upperCaseKeywords
                };

            var translator = new ExpressionTranslator(commandText, tree, null != tree.Returning, sqlGenerator);

            if (tree.SetClauses.Count == 0)
            {
                commandText.AppendKeyword("declare ");
                commandText.AppendLine(dummySetParameter + " int");
            }

            // update [schemaName].[tableName]
            commandText.AppendKeyword("update ");
            tree.Target.Expression.Accept(translator);
            commandText.AppendLine();

            // set c1 = ..., c2 = ..., ...
            var first = true;

            commandText.AppendKeyword("set ");
            foreach (DbSetClause setClause in tree.SetClauses)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    commandText.Append(", ");
                }
                setClause.Property.Accept(translator);
                commandText.Append(" = ");
                setClause.Value.Accept(translator);
            }

            if (first)
            {
                // If first is still true, it indicates there were no set
                // clauses. Introduce a fake set clause so that:
                // - we acquire the appropriate locks
                // - server-gen columns (e.g. timestamp) get recomputed
                //
                // We use the following pattern:
                //
                //  update Foo
                //  set @p = 0
                //  where ...
                commandText.Append(dummySetParameter + " = 0");
            }
            commandText.AppendLine();

            // where c1 = ..., c2 = ...
            commandText.AppendKeyword("where ");
            tree.Predicate.Accept(translator);
            commandText.AppendLine();

            if (generateReturningSql)
            {
                GenerateReturningSql(commandText, tree, null, translator, tree.Returning, false);
            }

            parameters = translator.Parameters;

            return(commandText.ToString());
        }
Exemple #9
0
        internal static string GenerateInsertSql(
            DbInsertCommandTree tree,
            SqlGenerator sqlGenerator,
            out List <SqlParameter> parameters,
            bool generateReturningSql = true,
            bool upperCaseKeywords    = true,
            bool createParameters     = true)
        {
            var commandText
                = new SqlStringBuilder(CommandTextBuilderInitialCapacity)
                {
                UpperCaseKeywords = upperCaseKeywords
                };

            var translator
                = new ExpressionTranslator(
                      commandText,
                      tree,
                      null != tree.Returning,
                      sqlGenerator,
                      createParameters: createParameters);

            var useGeneratedValuesVariable = UseGeneratedValuesVariable(tree, sqlGenerator.SqlVersion);
            var tableType = (EntityType)((DbScanExpression)tree.Target.Expression).Target.ElementType;

            if (useGeneratedValuesVariable)
            {
                // manufacture the variable, e.g. "declare @generated_values table(id uniqueidentifier)"
                commandText
                .AppendKeyword("declare ")
                .Append(GeneratedValuesVariableName)
                .Append(" table(");
                var first = true;
                foreach (var column in tableType.KeyMembers)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        commandText.Append(", ");
                    }
                    commandText
                    .Append(GenerateMemberTSql(column))
                    .Append(" ")
                    .Append(GetVariableType(sqlGenerator, column));
                    Facet collationFacet;
                    if (column.TypeUsage.Facets.TryGetValue(DbProviderManifest.CollationFacetName, false, out collationFacet))
                    {
                        var collation = collationFacet.Value as string;
                        if (!string.IsNullOrEmpty(collation))
                        {
                            commandText.AppendKeyword(" collate ").Append(collation);
                        }
                    }
                }
                Debug.Assert(!first, "if useGeneratedValuesVariable is true, it implies some columns do not have values");
                commandText.AppendLine(")");
            }

            // insert [schemaName].[tableName]
            commandText.AppendKeyword("insert ");
            tree.Target.Expression.Accept(translator);

            if (0 < tree.SetClauses.Count)
            {
                // (c1, c2, c3, ...)
                commandText.Append("(");
                var first = true;
                foreach (DbSetClause setClause in tree.SetClauses)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        commandText.Append(", ");
                    }
                    setClause.Property.Accept(translator);
                }
                commandText.AppendLine(")");
            }
            else
            {
                commandText.AppendLine();
            }

            if (useGeneratedValuesVariable)
            {
                // output inserted.id into @generated_values
                commandText.AppendKeyword("output ");
                var first = true;
                foreach (var column in tableType.KeyMembers)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        commandText.Append(", ");
                    }
                    commandText.Append("inserted.");
                    commandText.Append(GenerateMemberTSql(column));
                }
                commandText
                .AppendKeyword(" into ")
                .AppendLine(GeneratedValuesVariableName);
            }

            if (0 < tree.SetClauses.Count)
            {
                // values c1, c2, ...
                var first = true;
                commandText.AppendKeyword("values (");
                foreach (DbSetClause setClause in tree.SetClauses)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        commandText.Append(", ");
                    }
                    setClause.Value.Accept(translator);

                    translator.RegisterMemberValue(setClause.Property, setClause.Value);
                }
                commandText.AppendLine(")");
            }
            else
            {
                // default values
                commandText.AppendKeyword("default values");
                commandText.AppendLine();
            }

            if (generateReturningSql)
            {
                GenerateReturningSql(commandText, tree, tableType, translator, tree.Returning, useGeneratedValuesVariable);
            }

            parameters = translator.Parameters;

            return(commandText.ToString());
        }
        // <summary>
        // Generates SQL fragment returning server-generated values.
        // Requires: translator knows about member values so that we can figure out
        // how to construct the key predicate.
        // <code>Sample SQL:
        // 
        //     select IdentityValue
        //     from dbo.MyTable
        //     where @@ROWCOUNT > 0 and IdentityValue = scope_identity()
        // 
        //     or
        // 
        //     select TimestampValue
        //     from dbo.MyTable
        //     where @@ROWCOUNT > 0 and Id = 1
        // 
        //     Note that we filter on rowcount to ensure no rows are returned if no rows were modified.
        // 
        //     On SQL Server 2005 and up, we have an additional syntax used for non integer return types:
        // 
        //     declare @generatedValues table(ID uniqueidentifier)
        //     insert dbo.MyTable
        //     output ID into @generated_values
        //     values (...);
        //     select ID
        //     from @generatedValues as g join dbo.MyTable as t on g.ID = t.ID
        //     where @@ROWCOUNT > 0;</code>
        // </summary>
        // <param name="commandText"> Builder containing command text </param>
        // <param name="tree"> Modification command tree </param>
        // <param name="tableType"> Type of table. </param>
        // <param name="translator"> Translator used to produce DML SQL statement for the tree </param>
        // <param name="returning"> Returning expression. If null, the method returns immediately without producing a SELECT statement. </param>
        internal static void GenerateReturningSql(
            SqlStringBuilder commandText,
            DbModificationCommandTree tree,
            EntityType tableType,
            ExpressionTranslator translator,
            DbExpression returning,
            bool useGeneratedValuesVariable)
        {
            // Nothing to do if there is no Returning expression
            if (null == returning)
            {
                return;
            }

            // select
            commandText.AppendKeyword("select ");
            if (useGeneratedValuesVariable)
            {
                translator.PropertyAlias = "t";
            }
            returning.Accept(translator);
            if (useGeneratedValuesVariable)
            {
                translator.PropertyAlias = null;
            }
            commandText.AppendLine();

            if (useGeneratedValuesVariable)
            {
                // from @generated_keys
                commandText.AppendKeyword("from ");
                commandText.Append(GeneratedValuesVariableName);
                commandText.AppendKeyword(" as ");
                commandText.Append("g");
                commandText.AppendKeyword(" join ");
                tree.Target.Expression.Accept(translator);
                commandText.AppendKeyword(" as ");
                commandText.Append("t");
                commandText.AppendKeyword(" on ");
                var separator = string.Empty;
                foreach (var keyMember in tableType.KeyMembers)
                {
                    commandText.AppendKeyword(separator);
                    separator = " and ";
                    commandText.Append("g.");
                    var memberTSql = GenerateMemberTSql(keyMember);
                    commandText.Append(memberTSql);
                    commandText.Append(" = t.");
                    commandText.Append(memberTSql);
                }
                commandText.AppendLine();
                commandText.AppendKeyword("where @@ROWCOUNT > 0");
            }
            else
            {
                // from
                commandText.AppendKeyword("from ");
                tree.Target.Expression.Accept(translator);
                commandText.AppendLine();

                // where
                commandText.AppendKeyword("where @@ROWCOUNT > 0");
                var table = ((DbScanExpression)tree.Target.Expression).Target;
                var identity = false;
                foreach (var keyMember in table.ElementType.KeyMembers)
                {
                    commandText.AppendKeyword(" and ");
                    commandText.Append(GenerateMemberTSql(keyMember));
                    commandText.Append(" = ");

                    // retrieve member value sql. the translator remembers member values
                    // as it constructs the DML statement (which precedes the "returning"
                    // SQL)
                    SqlParameter value;
                    if (translator.MemberValues.TryGetValue(keyMember, out value))
                    {
                        commandText.Append(value.ParameterName);
                    }
                    else
                    {
                        // if no value is registered for the key member, it means it is an identity
                        // which can be retrieved using the scope_identity() function
                        if (identity)
                        {
                            // there can be only one server generated key
                            throw new NotSupportedException(Strings.Update_NotSupportedServerGenKey(table.Name));
                        }

                        if (!IsValidScopeIdentityColumnType(keyMember.TypeUsage))
                        {
                            throw new InvalidOperationException(
                                Strings.Update_NotSupportedIdentityType(
                                    keyMember.Name, keyMember.TypeUsage.ToString()));
                        }

                        commandText.Append("scope_identity()");
                        identity = true;
                    }
                }
            }
        }
        internal static string GenerateUpdateSql(
            DbUpdateCommandTree tree,
            SqlGenerator sqlGenerator,
            out List<SqlParameter> parameters,
            bool generateReturningSql = true,
            bool upperCaseKeywords = true)
        {
            const string dummySetParameter = "@p";

            var commandText
                = new SqlStringBuilder(CommandTextBuilderInitialCapacity)
                      {
                          UpperCaseKeywords = upperCaseKeywords
                      };

            var translator = new ExpressionTranslator(commandText, tree, null != tree.Returning, sqlGenerator);

            if (tree.SetClauses.Count == 0)
            {
                commandText.AppendKeyword("declare ");
                commandText.AppendLine(dummySetParameter + " int");
            }

            // update [schemaName].[tableName]
            commandText.AppendKeyword("update ");
            tree.Target.Expression.Accept(translator);
            commandText.AppendLine();

            // set c1 = ..., c2 = ..., ...
            var first = true;
            commandText.AppendKeyword("set ");
            foreach (DbSetClause setClause in tree.SetClauses)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    commandText.Append(", ");
                }
                setClause.Property.Accept(translator);
                commandText.Append(" = ");
                setClause.Value.Accept(translator);
            }

            if (first)
            {
                // If first is still true, it indicates there were no set
                // clauses. Introduce a fake set clause so that:
                // - we acquire the appropriate locks
                // - server-gen columns (e.g. timestamp) get recomputed
                //
                // We use the following pattern:
                //
                //  update SomeTable
                //  set @p = 0
                //  where ...
                commandText.Append(dummySetParameter + " = 0");
            }
            commandText.AppendLine();

            // where c1 = ..., c2 = ...
            commandText.AppendKeyword("where ");
            tree.Predicate.Accept(translator);
            commandText.AppendLine();

            if (generateReturningSql)
            {
                GenerateReturningSql(commandText, tree, null, translator, tree.Returning, false);
            }

            parameters = translator.Parameters;

            return commandText.ToString();
        }
        internal static string GenerateInsertSql(
            DbInsertCommandTree tree,
            SqlGenerator sqlGenerator,
            out List<SqlParameter> parameters,
            bool generateReturningSql = true,
            bool upperCaseKeywords = true,
            bool createParameters = true)
        {
            var commandText
                = new SqlStringBuilder(CommandTextBuilderInitialCapacity)
                      {
                          UpperCaseKeywords = upperCaseKeywords
                      };

            var translator
                = new ExpressionTranslator(
                    commandText,
                    tree,
                    null != tree.Returning,
                    sqlGenerator,
                    createParameters: createParameters);

            var useGeneratedValuesVariable = UseGeneratedValuesVariable(tree, sqlGenerator.SqlVersion);
            var tableType = (EntityType)((DbScanExpression)tree.Target.Expression).Target.ElementType;

            if (useGeneratedValuesVariable)
            {
                // manufacture the variable, e.g. "declare @generated_values table(id uniqueidentifier)"
                commandText
                    .AppendKeyword("declare ")
                    .Append(GeneratedValuesVariableName)
                    .Append(" table(");
                var first = true;
                foreach (var column in tableType.KeyMembers)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        commandText.Append(", ");
                    }
                    commandText
                        .Append(GenerateMemberTSql(column))
                        .Append(" ")
                        .Append(GetVariableType(sqlGenerator, column));
                    Facet collationFacet;
                    if (column.TypeUsage.Facets.TryGetValue(DbProviderManifest.CollationFacetName, false, out collationFacet))
                    {
                        var collation = collationFacet.Value as string;
                        if (!string.IsNullOrEmpty(collation))
                        {
                            commandText.AppendKeyword(" collate ").Append(collation);
                        }
                    }
                }
                Debug.Assert(!first, "if useGeneratedValuesVariable is true, it implies some columns do not have values");
                commandText.AppendLine(")");
            }

            // insert [schemaName].[tableName]
            commandText.AppendKeyword("insert ");
            tree.Target.Expression.Accept(translator);

            if (0 < tree.SetClauses.Count)
            {
                // (c1, c2, c3, ...)
                commandText.Append("(");
                var first = true;
                foreach (DbSetClause setClause in tree.SetClauses)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        commandText.Append(", ");
                    }
                    setClause.Property.Accept(translator);
                }
                commandText.AppendLine(")");
            }
            else
            {
                commandText.AppendLine();
            }

            if (useGeneratedValuesVariable)
            {
                // output inserted.id into @generated_values
                commandText.AppendKeyword("output ");
                var first = true;
                foreach (var column in tableType.KeyMembers)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        commandText.Append(", ");
                    }
                    commandText.Append("inserted.");
                    commandText.Append(GenerateMemberTSql(column));
                }
                commandText
                    .AppendKeyword(" into ")
                    .AppendLine(GeneratedValuesVariableName);
            }

            if (0 < tree.SetClauses.Count)
            {
                // values c1, c2, ...
                var first = true;
                commandText.AppendKeyword("values (");
                foreach (DbSetClause setClause in tree.SetClauses)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        commandText.Append(", ");
                    }
                    setClause.Value.Accept(translator);

                    translator.RegisterMemberValue(setClause.Property, setClause.Value);
                }
                commandText.AppendLine(")");
            }
            else
            {
                // default values
                commandText.AppendKeyword("default values");
                commandText.AppendLine();
            }

            if (generateReturningSql)
            {
                GenerateReturningSql(commandText, tree, tableType, translator, tree.Returning, useGeneratedValuesVariable);
            }

            parameters = translator.Parameters;

            return commandText.ToString();
        }
        internal static string GenerateDeleteSql(
            DbDeleteCommandTree tree,
            SqlGenerator sqlGenerator,
            out List<SqlParameter> parameters,
            bool upperCaseKeywords = true,
            bool createParameters = true)
        {
            var commandText
                = new SqlStringBuilder(CommandTextBuilderInitialCapacity)
                      {
                          UpperCaseKeywords = upperCaseKeywords
                      };

            var translator 
                = new ExpressionTranslator(
                    commandText, 
                    tree, 
                    false, 
                    sqlGenerator,
                    createParameters: createParameters);

            // delete [schemaName].[tableName]
            commandText.AppendKeyword("delete ");
            tree.Target.Expression.Accept(translator);
            commandText.AppendLine();

            // where c1 = ... AND c2 = ...
            commandText.AppendKeyword("where ");
            tree.Predicate.Accept(translator);

            parameters = translator.Parameters;
            return commandText.ToString();
        }
        internal static string GenerateInsertSql(
            DbInsertCommandTree tree,
            SqlGenerator sqlGenerator,
            out List <SqlParameter> parameters,
            bool generateReturningSql = true,
            bool upperCaseKeywords    = true,
            bool createParameters     = true)
        {
            SqlStringBuilder commandText = new SqlStringBuilder(256)
            {
                UpperCaseKeywords = upperCaseKeywords
            };

            DmlSqlGenerator.ExpressionTranslator translator = new DmlSqlGenerator.ExpressionTranslator(commandText, (DbModificationCommandTree)tree, null != tree.Returning, sqlGenerator, (ICollection <EdmProperty>)null, createParameters);
            bool       useGeneratedValuesVariable           = DmlSqlGenerator.UseGeneratedValuesVariable(tree, sqlGenerator.SqlVersion);
            EntityType elementType = (EntityType)((DbScanExpression)tree.Target.Expression).Target.ElementType;

            if (useGeneratedValuesVariable)
            {
                commandText.AppendKeyword("declare ").Append("@generated_keys").Append(" table(");
                bool flag = true;
                foreach (EdmMember keyMember in elementType.KeyMembers)
                {
                    if (flag)
                    {
                        flag = false;
                    }
                    else
                    {
                        commandText.Append(", ");
                    }
                    commandText.Append(DmlSqlGenerator.GenerateMemberTSql(keyMember)).Append(" ").Append(DmlSqlGenerator.GetVariableType(sqlGenerator, keyMember));
                    Facet facet;
                    if (keyMember.TypeUsage.Facets.TryGetValue("Collation", false, out facet))
                    {
                        string s = facet.Value as string;
                        if (!string.IsNullOrEmpty(s))
                        {
                            commandText.AppendKeyword(" collate ").Append(s);
                        }
                    }
                }
                commandText.AppendLine(")");
            }
            commandText.AppendKeyword("insert ");
            tree.Target.Expression.Accept((DbExpressionVisitor)translator);
            if (0 < tree.SetClauses.Count)
            {
                commandText.Append("(");
                bool flag = true;
                foreach (DbSetClause setClause in (IEnumerable <DbModificationClause>)tree.SetClauses)
                {
                    if (flag)
                    {
                        flag = false;
                    }
                    else
                    {
                        commandText.Append(", ");
                    }
                    setClause.Property.Accept((DbExpressionVisitor)translator);
                }
                commandText.AppendLine(")");
            }
            else
            {
                commandText.AppendLine();
            }
            if (useGeneratedValuesVariable)
            {
                commandText.AppendKeyword("output ");
                bool flag = true;
                foreach (EdmMember keyMember in elementType.KeyMembers)
                {
                    if (flag)
                    {
                        flag = false;
                    }
                    else
                    {
                        commandText.Append(", ");
                    }
                    commandText.Append("inserted.");
                    commandText.Append(DmlSqlGenerator.GenerateMemberTSql(keyMember));
                }
                commandText.AppendKeyword(" into ").AppendLine("@generated_keys");
            }
            if (0 < tree.SetClauses.Count)
            {
                bool flag = true;
                commandText.AppendKeyword("values (");
                foreach (DbSetClause setClause in (IEnumerable <DbModificationClause>)tree.SetClauses)
                {
                    if (flag)
                    {
                        flag = false;
                    }
                    else
                    {
                        commandText.Append(", ");
                    }
                    setClause.Value.Accept((DbExpressionVisitor)translator);
                    translator.RegisterMemberValue(setClause.Property, setClause.Value);
                }
                commandText.AppendLine(")");
            }
            else
            {
                commandText.AppendKeyword("default values");
                commandText.AppendLine();
            }
            if (generateReturningSql)
            {
                DmlSqlGenerator.GenerateReturningSql(commandText, (DbModificationCommandTree)tree, elementType, translator, tree.Returning, useGeneratedValuesVariable);
            }
            parameters = translator.Parameters;
            return(commandText.ToString());
        }
 internal static void GenerateReturningSql(
     SqlStringBuilder commandText,
     DbModificationCommandTree tree,
     EntityType tableType,
     DmlSqlGenerator.ExpressionTranslator translator,
     DbExpression returning,
     bool useGeneratedValuesVariable)
 {
     if (returning == null)
     {
         return;
     }
     commandText.AppendKeyword("select ");
     if (useGeneratedValuesVariable)
     {
         translator.PropertyAlias = "t";
     }
     returning.Accept((DbExpressionVisitor)translator);
     if (useGeneratedValuesVariable)
     {
         translator.PropertyAlias = (string)null;
     }
     commandText.AppendLine();
     if (useGeneratedValuesVariable)
     {
         commandText.AppendKeyword("from ");
         commandText.Append("@generated_keys");
         commandText.AppendKeyword(" as ");
         commandText.Append("g");
         commandText.AppendKeyword(" join ");
         tree.Target.Expression.Accept((DbExpressionVisitor)translator);
         commandText.AppendKeyword(" as ");
         commandText.Append("t");
         commandText.AppendKeyword(" on ");
         string keyword = string.Empty;
         foreach (EdmMember keyMember in tableType.KeyMembers)
         {
             commandText.AppendKeyword(keyword);
             keyword = " and ";
             commandText.Append("g.");
             string memberTsql = DmlSqlGenerator.GenerateMemberTSql(keyMember);
             commandText.Append(memberTsql);
             commandText.Append(" = t.");
             commandText.Append(memberTsql);
         }
         commandText.AppendLine();
         commandText.AppendKeyword("where @@ROWCOUNT > 0");
     }
     else
     {
         commandText.AppendKeyword("from ");
         tree.Target.Expression.Accept((DbExpressionVisitor)translator);
         commandText.AppendLine();
         commandText.AppendKeyword("where @@ROWCOUNT > 0");
         EntitySetBase target = ((DbScanExpression)tree.Target.Expression).Target;
         bool          flag   = false;
         foreach (EdmMember keyMember in target.ElementType.KeyMembers)
         {
             commandText.AppendKeyword(" and ");
             commandText.Append(DmlSqlGenerator.GenerateMemberTSql(keyMember));
             commandText.Append(" = ");
             SqlParameter sqlParameter;
             if (translator.MemberValues.TryGetValue(keyMember, out sqlParameter))
             {
                 commandText.Append(sqlParameter.ParameterName);
             }
             else
             {
                 if (flag)
                 {
                     throw new NotSupportedException(Strings.Update_NotSupportedServerGenKey((object)target.Name));
                 }
                 if (!DmlSqlGenerator.IsValidScopeIdentityColumnType(keyMember.TypeUsage))
                 {
                     throw new InvalidOperationException(Strings.Update_NotSupportedIdentityType((object)keyMember.Name, (object)keyMember.TypeUsage.ToString()));
                 }
                 commandText.Append("scope_identity()");
                 flag = true;
             }
         }
     }
 }