private string IntroduceRequiredLocalVariables( EntityType entityType, DbInsertCommandTree commandTree) { List <EdmProperty> list = entityType.KeyProperties.Where <EdmProperty>((Func <EdmProperty, bool>)(p => p.IsStoreGeneratedIdentity)).ToList <EdmProperty>(); SqlStringBuilder commandText = new SqlStringBuilder() { UpperCaseKeywords = true }; if (list.Any <EdmProperty>()) { foreach (EdmProperty edmProperty in list) { commandText.Append(commandText.Length == 0 ? "DECLARE " : ", "); commandText.Append("@"); commandText.Append(edmProperty.Name); commandText.Append(" "); commandText.Append(DmlSqlGenerator.GetVariableType(this._sqlGenerator, (EdmMember)edmProperty)); } commandText.AppendLine(); DmlSqlGenerator.ExpressionTranslator translator = new DmlSqlGenerator.ExpressionTranslator(commandText, (DbModificationCommandTree)commandTree, true, this._sqlGenerator, (ICollection <EdmProperty>)entityType.KeyProperties, true); DmlSqlGenerator.GenerateReturningSql(commandText, (DbModificationCommandTree)commandTree, entityType, translator, commandTree.Returning, DmlSqlGenerator.UseGeneratedValuesVariable(commandTree, this._sqlGenerator.SqlVersion)); commandText.AppendLine(); commandText.AppendLine(); } return(commandText.ToString()); }
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()); }
private string IntroduceRequiredLocalVariables(EntityType entityType, DbInsertCommandTree commandTree) { DebugCheck.NotNull(entityType); DebugCheck.NotNull(commandTree); var storeGeneratedKeys = entityType .KeyProperties .Where(p => p.IsStoreGeneratedIdentity) .ToList(); var sql = new SqlStringBuilder { UpperCaseKeywords = true }; if (storeGeneratedKeys.Any()) { foreach (var keyProperty in storeGeneratedKeys) { sql.Append(sql.Length == 0 ? "DECLARE " : ", "); sql.Append("@"); sql.Append(keyProperty.Name); sql.Append(" "); sql.Append(DmlSqlGenerator.GetVariableType(_sqlGenerator, keyProperty)); } sql.AppendLine(); var translator = new DmlSqlGenerator.ExpressionTranslator( sql, commandTree, true, _sqlGenerator, entityType.KeyProperties); DmlSqlGenerator.GenerateReturningSql( sql, commandTree, entityType, translator, commandTree.Returning, DmlSqlGenerator.UseGeneratedValuesVariable(commandTree, _sqlGenerator.SqlVersion)); sql.AppendLine(); sql.AppendLine(); } return(sql.ToString()); }
public void Methods_should_delegate_to_underlying_string_builder() { var sqlStringBuilder = new SqlStringBuilder(); sqlStringBuilder.Append("foo"); sqlStringBuilder.AppendLine("bar"); sqlStringBuilder.AppendLine(); Assert.Equal(10, sqlStringBuilder.Length); }
public void Methods_should_delegate_to_underlying_string_builder() { var sqlStringBuilder = new SqlStringBuilder(); sqlStringBuilder.Append("foo"); sqlStringBuilder.AppendLine("bar"); sqlStringBuilder.AppendLine(); Assert.Equal(10, sqlStringBuilder.Length); }
public override void Visit(DbNotExpression expression) { Check.NotNull(expression, "expression"); _commandText.AppendKeyword("not ("); expression.Accept(this); _commandText.Append(")"); }
/// <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 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()); }
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(); }
private string IntroduceRequiredLocalVariables(EntityType entityType, DbInsertCommandTree commandTree) { DebugCheck.NotNull(entityType); DebugCheck.NotNull(commandTree); var storeGeneratedKeys = entityType .KeyProperties .Where(p => p.IsStoreGeneratedIdentity) .ToList(); var sql = new SqlStringBuilder { UpperCaseKeywords = true }; if (storeGeneratedKeys.Any()) { foreach (var keyProperty in storeGeneratedKeys) { sql.Append(sql.Length == 0 ? "DECLARE " : ", "); sql.Append("@"); sql.Append(keyProperty.Name); sql.Append(" "); sql.Append(DmlSqlGenerator.GetVariableType(_sqlGenerator, keyProperty)); } sql.AppendLine(); var translator = new DmlSqlGenerator.ExpressionTranslator( sql, commandTree, true, _sqlGenerator, entityType.KeyProperties); DmlSqlGenerator.GenerateReturningSql( sql, commandTree, entityType, translator, commandTree.Returning, DmlSqlGenerator.UseGeneratedValuesVariable(commandTree, _sqlGenerator.SqlVersion)); sql.AppendLine(); sql.AppendLine(); } return sql.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; } } } }