in EFCore/src/Migrations/MySQLMigrationsSqlGenerator.cs [232:347]
protected override void ColumnDefinition(AddColumnOperation operation, IModel? model,
MigrationCommandListBuilder builder)
=> ColumnDefinition(
operation.Schema,
operation.Table,
operation.Name,
operation,
model,
builder);
/// <summary>
/// Generates a SQL fragment for a column definition for the given column metadata.
/// </summary>
/// <param name="schema"> The schema that contains the table, or <c>null</c> to use the default schema. </param>
/// <param name="table"> The table that contains the column. </param>
/// <param name="name"> The column name. </param>
/// <param name="operation"> The column metadata. </param>
/// <param name="model"> The target model, which may be <c>null</c> if the operations exist without a model. </param>
/// <param name="builder"> The command builder to use to add the SQL fragment. </param>
protected override void ColumnDefinition(
string? schema,
string table,
string name,
ColumnOperation operation,
IModel? model,
MigrationCommandListBuilder builder)
{
Check.NotEmpty(name, nameof(name));
Check.NotNull(operation, nameof(operation));
Check.NotNull(builder, nameof(builder));
var matchType = operation.ColumnType ?? GetColumnType(schema, table, name, operation, model);
var matchLen = "";
var match = _typeRegex.Match(matchType ?? "-");
if (match.Success)
{
matchType = match.Groups[1].Value.ToLower();
if (!string.IsNullOrWhiteSpace(match.Groups[2].Value))
{
matchLen = match.Groups[2].Value;
}
}
var valueGenerationStrategy = MySQLValueGenerationStrategyCompatibility.GetValueGenerationStrategy(operation.GetAnnotations().OfType<IAnnotation>().ToArray());
var autoIncrement = false;
if (valueGenerationStrategy == MySQLValueGenerationStrategy.IdentityColumn &&
string.IsNullOrWhiteSpace(operation.DefaultValueSql) && operation.DefaultValue == null)
{
switch (matchType)
{
case "tinyint":
case "smallint":
case "mediumint":
case "int":
case "bigint":
autoIncrement = true;
break;
case "datetime":
case "timestamp":
operation.DefaultValueSql = $"CURRENT_TIMESTAMP({matchLen})";
break;
}
}
string? onUpdateSql = null;
if (operation.IsRowVersion || valueGenerationStrategy == MySQLValueGenerationStrategy.ComputedColumn)
{
switch (matchType)
{
case "datetime":
case "timestamp":
if (string.IsNullOrWhiteSpace(operation.DefaultValueSql) && operation.DefaultValue == null)
{
operation.DefaultValueSql = $"CURRENT_TIMESTAMP({matchLen})";
}
onUpdateSql = $"CURRENT_TIMESTAMP({matchLen})";
break;
}
}
if (operation.ComputedColumnSql == null)
{
ColumnDefinitionWithCharSet(schema, table, name, operation, model, builder);
if (autoIncrement)
{
builder.Append(" AUTO_INCREMENT");
}
else
{
if (onUpdateSql != null)
{
builder
.Append(" ON UPDATE ")
.Append(onUpdateSql);
}
}
}
else
{
builder
.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(name))
.Append(" ")
.Append(operation.ColumnType ?? GetColumnType(schema, table, name, operation, model));
builder
.Append(" AS ")
.Append($"({operation.ComputedColumnSql})");
if (operation.IsNullable)
{
builder.Append(" NULL");
}
}
}