protected override void OnVisit(ExpressionVisitorContext context, TableDefinition statement) { if (statement.IsTemporary) { context.WriteLine($"CREATE TABLE #{statement.Name} ("); } else { context.WriteLine($"CREATE TABLE {statement.Name} ("); } int index = 0; foreach (var field in statement.Fields) { if (index++ > 0) { context.WriteLine(","); } context.Visit(field); } context.WriteLine(");"); }
protected override void VisitTables(ExpressionVisitorContext context, UpdateStatement statement, IList <TableIdentifier> tables) { //调用基类同名方法 base.VisitTables(context, statement, tables); /* * 注意:由于 MySQL 的 UPDATE 语句不支持 FROM 子句,因此必须将其改写为多表修改的语法。 */ if (statement.HasFrom) { foreach (var source in statement.From) { switch (source) { case TableIdentifier table: if (!tables.Contains(table)) { context.Write(","); context.Visit(table); } break; case JoinClause join: if (join.Target is TableIdentifier target) { if (!tables.Contains(target)) { context.Write(","); context.Visit(target); } } else { throw new DataException($"The {MySqlDriver.Key} driver does not support the FROM clause of the UPDATE statement contain an expression of type '{join.Target.GetType().Name}'."); } break; default: throw new NotSupportedException($"The {MySqlDriver.Key} driver does not support the FROM clause of the UPDATE statement contain an expression of type '{source.GetType().Name}'."); } } } }
protected override void VisitTables(ExpressionVisitorContext context, UpdateStatement statement, IList <TableIdentifier> tables) { if (tables.Count > 1) { throw new DataException("The generated Update statement is incorrect, The data engine does not support multi-table updates."); } if (string.IsNullOrEmpty(tables[0].Alias)) { context.Visit(tables[0]); } else { context.Write(tables[0].Alias); } }
protected override void OnVisit(ExpressionVisitorContext context, UpsertStatement statement) { if (statement.Fields == null || statement.Fields.Count == 0) { throw new DataException("Missing required fields in the upsert statment."); } var index = 0; context.Write("INSERT INTO "); //visitor.Visit(statement.Table); context.Write(context.Dialect.GetIdentifier(statement.Table)); context.Write(" ("); foreach (var field in statement.Fields) { if (index++ > 0) { context.Write(","); } //visitor.Visit(field); context.Write(context.Dialect.GetIdentifier(field.Name)); } index = 0; context.WriteLine(") VALUES "); foreach (var value in statement.Values) { if (index++ > 0) { context.Write(","); } if (index % statement.Fields.Count == 1) { context.Write("("); } var parenthesisRequired = value is IStatementBase; if (parenthesisRequired) { context.Write("("); } context.Visit(value); if (parenthesisRequired) { context.Write(")"); } if (index % statement.Fields.Count == 0) { context.Write(")"); } } index = 0; context.WriteLine(" ON DUPLICATE KEY UPDATE "); if (statement.Updation.Count > 0) { foreach (var item in statement.Updation) { if (index++ > 0) { context.Write(","); } context.Write(context.Dialect.GetIdentifier(item.Field)); context.Write("="); var parenthesisRequired = item.Value is IStatementBase; if (parenthesisRequired) { context.Write("("); } context.Visit(item.Value); if (parenthesisRequired) { context.Write(")"); } } } else { foreach (var field in statement.Fields) { //忽略修改序列字段 if (field.Token.Property is Metadata.IDataEntitySimplexProperty simplex && simplex.Sequence != null) { continue; } if (index++ > 0) { context.Write(","); } context.Write(context.Dialect.GetIdentifier(field.Name)); context.Write("=VALUES("); context.Write(context.Dialect.GetIdentifier(field.Name)); context.Write(")"); } } context.WriteLine(";"); }
protected override void OnVisit(ExpressionVisitorContext context, UpsertStatement statement) { const string SOURCE_ALIAS = "SRC"; const string TARGET_ALIAS = "TAR"; if (statement.Fields == null || statement.Fields.Count == 0) { throw new DataException("Missing required fields in the upsert statment."); } context.Write("MERGE INTO "); context.Visit(statement.Table); //visitor.Output.Append(" AS " + TARGET_ALIAS); context.WriteLine(" USING (SELECT "); for (int i = 0; i < statement.Values.Count; i++) { if (i > 0) { context.Write(","); } context.Visit(statement.Values[i]); } context.WriteLine(") AS " + SOURCE_ALIAS + " ("); for (int i = 0; i < statement.Fields.Count; i++) { if (i > 0) { context.Write(","); } context.Write("[" + statement.Fields[i].Name + "]"); } context.WriteLine(") ON"); for (int i = 0; i < statement.Entity.Key.Length; i++) { var field = Metadata.DataEntityPropertyExtension.GetFieldName(statement.Entity.Key[i], out _); if (i > 0) { context.Write(" AND "); } if (string.IsNullOrEmpty(statement.Table.Alias)) { context.Write($"[{field}]={SOURCE_ALIAS}.[{field}]"); } else { context.Write($"{statement.Table.Alias}.[{field}]={SOURCE_ALIAS}.[{field}]"); } } if (statement.Updation.Count > 0) { context.WriteLine(); context.Write("WHEN MATCHED"); if (statement.Where != null) { context.WriteLine(" AND "); context.Visit(statement.Where); } context.WriteLine(" THEN"); context.Write("\tUPDATE SET "); int index = 0; foreach (var item in statement.Updation) { if (index++ > 0) { context.Write(","); } context.Visit(item.Field); context.Write("="); var parenthesisRequired = item.Value is IStatementBase; if (parenthesisRequired) { context.Write("("); } context.Visit(item.Value); if (parenthesisRequired) { context.Write(")"); } } } context.WriteLine(); context.WriteLine("WHEN NOT MATCHED THEN"); context.Write("\tINSERT ("); for (int i = 0; i < statement.Fields.Count; i++) { if (i > 0) { context.Write(","); } context.Write(context.Dialect.GetIdentifier(statement.Fields[i])); } context.Write(") VALUES ("); for (int i = 0; i < statement.Fields.Count; i++) { if (i > 0) { context.Write(","); } context.Write(SOURCE_ALIAS + ".[" + statement.Fields[i].Name + "]"); } context.Write(")"); //输出返回子句 this.VisitOutput(context, statement.Returning); context.WriteLine(";"); }