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)); }
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)); }
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); }
protected override void WriteInsertIntoReturning(SqlInsertIntoExpression expression) { if (expression.ReturningAutoIncrementColumnNames == null || expression.ReturningAutoIncrementColumnNames.Count == 0) { return; } this.Write("; SELECT last_insert_rowid()"); }
protected override void WriteInsertIntoReturning(SqlInsertIntoExpression expression) { if (expression.ReturningAutoIncrementColumnNames == null || expression.ReturningAutoIncrementColumnNames.Count == 0) { return; } Write("; SELECT LAST_INSERT_ID()"); }
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, ","); }
protected override bool WriteInsertIntoAfterSource(SqlInsertIntoExpression expression) { var tableHintExpression = expression.WithExpression as SqlTableHintExpression; if (tableHintExpression?.TableLock == true) { Write(" WITH (TABLOCK) "); } return(true); }
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); }
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)); }
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(""); }
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); }
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); }
protected override Expression VisitInsertInto(SqlInsertIntoExpression insertIntoExpression) { return(insertIntoExpression); }
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(); } } }
protected virtual Expression VisitInsertInto(SqlInsertIntoExpression expression) { return(expression); }