internal override SqlStatement VisitInsert(SqlInsert sin) { SqlScope save = this.CurrentScope; this.CurrentScope = new SqlScope(sin, this.CurrentScope.ContainingScope); base.VisitInsert(sin); this.CurrentScope = save; return sin; }
internal override SqlStatement VisitInsert(SqlInsert insert) { bool saveMakeUnique = this.makeUnique; this.makeUnique = false; bool saveUseMappedNames = this.useMappedNames; this.useMappedNames = true; SqlStatement stmt = base.VisitInsert(insert); this.makeUnique = saveMakeUnique; this.useMappedNames = saveUseMappedNames; return stmt; }
internal virtual SqlStatement VisitInsert(SqlInsert insert) { insert.Table = (SqlTable)this.Visit(insert.Table); insert.Expression = this.VisitExpression(insert.Expression); insert.Row = (SqlRow)this.Visit(insert.Row); return insert; }
private SqlStatement VisitInsert(Expression item, LambdaExpression resultSelector) { if(item == null) { throw Error.ArgumentNull("item"); } _dominatingExpression = item; MetaTable metaTable = _services.Model.GetTable(item.Type); Expression source = _services.Context.GetTable(metaTable.RowType.Type).Expression; MetaType itemMetaType = null; SqlNew sqlItem = null; // construct insert assignments from 'item' info ConstantExpression conItem = item as ConstantExpression; if(conItem == null) { throw Error.InsertItemMustBeConstant(); } if(conItem.Value == null) { throw Error.ArgumentNull("item"); } // construct insert based on constant value List<SqlMemberAssign> bindings = new List<SqlMemberAssign>(); itemMetaType = metaTable.RowType.GetInheritanceType(conItem.Value.GetType()); SqlExpression sqlExprItem = _nodeFactory.ValueFromObject(conItem.Value, true, source); foreach(MetaDataMember mm in itemMetaType.PersistentDataMembers) { if(!mm.IsAssociation && !mm.IsDbGenerated && !mm.IsVersion) { bindings.Add(new SqlMemberAssign(mm.Member, _nodeFactory.Member(sqlExprItem, mm.Member))); } } ConstructorInfo cons = itemMetaType.Type.GetConstructor(Type.EmptyTypes); System.Diagnostics.Debug.Assert(cons != null); sqlItem = _nodeFactory.New(itemMetaType, cons, null, null, bindings, item); SqlTable tab = _nodeFactory.Table(metaTable, metaTable.RowType, _dominatingExpression); SqlInsert sin = new SqlInsert(tab, sqlItem, item); if(resultSelector == null) { return sin; } else { MetaDataMember id = itemMetaType.DBGeneratedIdentityMember; bool isDbGenOnly = false; if(id != null) { isDbGenOnly = this.IsDbGeneratedKeyProjectionOnly(resultSelector.Body, id); if(id.Type == typeof(Guid) && (_converterStrategy & ConverterStrategy.CanOutputFromInsert) != 0) { sin.OutputKey = new SqlColumn(id.Type, _nodeFactory.Default(id), id.Name, id, null, _dominatingExpression); if(!isDbGenOnly) { sin.OutputToLocal = true; } } } SqlSelect result = null; SqlSelect preResult = null; SqlAlias tableAlias = new SqlAlias(tab); SqlAliasRef tableAliasRef = new SqlAliasRef(tableAlias); System.Diagnostics.Debug.Assert(resultSelector.Parameters.Count == 1); _parameterExpressionToSqlExpression.Add(resultSelector.Parameters[0], tableAliasRef); SqlExpression projection = this.VisitExpression(resultSelector.Body); // build select to return result SqlExpression pred = null; if(id != null) { pred = _nodeFactory.Binary( SqlNodeType.EQ, _nodeFactory.Member(tableAliasRef, id.Member), this.GetIdentityExpression(id, sin.OutputKey != null) ); } else { SqlExpression itemExpression = this.VisitExpression(item); pred = _nodeFactory.Binary(SqlNodeType.EQ2V, tableAliasRef, itemExpression); } result = new SqlSelect(projection, tableAlias, resultSelector); result.Where = pred; // Since we're only projecting back a single generated key, we can // optimize the query to a simple selection (e.g. SELECT @@IDENTITY) // rather than selecting back from the table. if(id != null && isDbGenOnly) { if(sin.OutputKey == null) { SqlExpression exp = this.GetIdentityExpression(id, false); if(exp.ClrType != id.Type) { ProviderType sqlType = _nodeFactory.Default(id); exp = _nodeFactory.ConvertTo(id.Type, sqlType, exp); } // The result selector passed in was bound to the table - // we need to rebind to the single result as an array projection ParameterExpression p = Expression.Parameter(id.Type, "p"); Expression[] init = new Expression[1] { Expression.Convert(p, typeof(object)) }; NewArrayExpression arrExp = Expression.NewArrayInit(typeof(object), init); LambdaExpression rs = Expression.Lambda(arrExp, p); _parameterExpressionToSqlExpression.Add(p, exp); SqlExpression proj = this.VisitExpression(rs.Body); preResult = new SqlSelect(proj, null, rs); } else { // case handled in formatter automatically } result.DoNotOutput = true; } // combine insert & result into block SqlBlock block = new SqlBlock(_dominatingExpression); block.Statements.Add(sin); if(preResult != null) { block.Statements.Add(preResult); } block.Statements.Add(result); return block; } }
internal override SqlStatement VisitInsert(SqlInsert si) { if(si.OutputKey != null) { _commandStringBuilder.Append("DECLARE @output TABLE("); this.WriteName(si.OutputKey.Name); _commandStringBuilder.Append(" "); _commandStringBuilder.Append(si.OutputKey.SqlType.ToQueryString()); _commandStringBuilder.Append(")"); this.NewLine(); if(si.OutputToLocal) { _commandStringBuilder.Append("DECLARE @id "); _commandStringBuilder.Append(si.OutputKey.SqlType.ToQueryString()); this.NewLine(); } } _commandStringBuilder.Append("INSERT INTO "); this.Visit(si.Table); if(si.Row.Columns.Count != 0) { // INSERT INTO table (...columns...) VALUES (...values...) _commandStringBuilder.Append("("); for(int i = 0, n = si.Row.Columns.Count; i < n; i++) { if(i > 0) _commandStringBuilder.Append(", "); this.WriteName(si.Row.Columns[i].Name); } _commandStringBuilder.Append(")"); } if(si.OutputKey != null) { this.NewLine(); _commandStringBuilder.Append("OUTPUT INSERTED."); this.WriteName(si.OutputKey.MetaMember.MappedName); _commandStringBuilder.Append(" INTO @output"); } if(si.Row.Columns.Count == 0) { _commandStringBuilder.Append(" DEFAULT VALUES"); } else { // VALUES (...values...) this.NewLine(); _commandStringBuilder.Append("VALUES ("); if(_isDebugMode && si.Row.Columns.Count == 0) { this.Visit(si.Expression); } else { for(int i = 0, n = si.Row.Columns.Count; i < n; i++) { if(i > 0) _commandStringBuilder.Append(", "); this.Visit(si.Row.Columns[i].Expression); } } _commandStringBuilder.Append(")"); } if(si.OutputKey != null) { this.NewLine(); if(si.OutputToLocal) { _commandStringBuilder.Append("SELECT @id = "); _commandStringBuilder.Append(si.OutputKey.Name); _commandStringBuilder.Append(" FROM @output"); } else { _commandStringBuilder.Append("SELECT "); this.WriteName(si.OutputKey.Name); _commandStringBuilder.Append(" FROM @output"); } } return si; }
internal override SqlStatement VisitInsert(SqlInsert si) { SqlInsert n = new SqlInsert(si.Table, this.VisitExpression(si.Expression), si.SourceExpression); n.OutputKey = si.OutputKey; n.OutputToLocal = si.OutputToLocal; n.Row = this.VisitRow(si.Row); return n; }
internal override SqlStatement VisitInsert(SqlInsert sin) { base.VisitInsert(sin); sin.Expression = this.FlattenSelection(sin.Row, true, sin.Expression); return sin; }
internal override SqlStatement VisitInsert(SqlInsert sin) { bool saveTop = this.topLevel; this.topLevel = false; base.VisitInsert(sin); this.topLevel = saveTop; return sin; }