protected override void OnSave(string value) { base.OnSave(value); Model.Parameter = JsonHelper.Serialize(ParameterValues.ToDictionary(x => x.Name, x => x.Value)); }
/// <summary> /// Converts the SQL into an UPDATE statement. /// </summary> /// <param name="update">The field or fields to update.</param> /// <returns></returns> public ParameterizedSql <TEntity> ToUpdate(Expression <Func <TEntity, TEntity> > update) { if (ReadOnly) { throw new InvalidOperationException("The UPDATE SQL cannot be automatically generated from this statement."); } if (!IsSelect) { throw new InvalidOperationException("Only SELECT statements can be converted to UPDATE statements."); } if (IsGrouped) { throw new InvalidOperationException("An aggregate SELECT statement cannot be converted to an UPDATE statement."); } if (HasWithExpression) { throw new InvalidOperationException("A SELECT statement with a WITH clause cannot be converted to an UPDATE statement."); } if (!(update.Body is MemberInitExpression initExpression)) { throw new InvalidOperationException("The update expression must be a member initialization expression."); } var paramValues = ParameterValues.ToDictionary(x => x.Key, x => x.Value); var builder = new StringBuilder(); _logger?.LogDebug("Generating UPDATE SQL"); var context = DbContext ?? throw new InvalidOperationException("No current DbContext available."); var entityType = context.Model.FindEntityType(typeof(TEntity)) ?? throw new InvalidOperationException("Failed to locate entity type."); builder.Append("UPDATE "); string subAlias; if (_knowledge.UpdateSupportsTableAliases) { if (_knowledge.UpdateSupportsFromClause) { // UPDATE supports aliases and a FROM clause. builder.Append(_knowledge.QuoteObjectName(_tableAlias)).Append(" SET "); } else { // UPDATE supports aliases, but not the from clause (MySQL, MariaDB) // The tables and aliases are specified immediately following the UPDATE keyword, so we can // trim off the FROM keyword and just append the rest of the from clause. builder.Append(_fromClause.Substring(5)).Append(" SET "); } subAlias = _knowledge.QuoteObjectName(_tableAlias) + "."; } else { builder.Append(_tableName).Append(" SET "); subAlias = ""; } bool first = true; foreach (var binding in initExpression.Bindings) { if (!(binding is MemberAssignment assignment)) { throw new InvalidOperationException("Only simple assignment bindings are supported in the update expression."); } if (!first) { builder.Append(", "); } first = false; var prop = entityType.FindProperty(assignment.Member.Name) ?? throw new InvalidOperationException( $"The entity does not contain a {assignment.Member.Name} property." ); builder.Append(subAlias); builder.Append(ColumnNameFor(prop)).Append(" = "); AddColumnValue(assignment.Expression, builder, paramValues, context, entityType); } if (_knowledge.UpdateSupportsTableAliases) { if (_knowledge.UpdateSupportsFromClause) { builder.Append(' ').Append(_fromClause); } builder.Append(' ').Append(_whereClause); } else { builder.Append(' ').Append(GenerateUnAliasedWhereClause()); } var sql = builder.ToString().Trim(); _logger?.LogDebug(sql); return(new ParameterizedSql <TEntity>( this, "UPDATE", sql, paramValues )); }