创建一个这样的表:
create table TimestampTable(
Id int not null,
Ts timestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
Dt datetime default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
primary key (Id)
);
跑步:
dotnet ef dbcontext scaffold \
--data-annotations \
--context TestDb \
--force \
--use-database-names \
"my_connection_string" \
"Pomelo.EntityFrameworkCore.MySql"
Pomelo 设置默认值'CURRENT_TIMESTAMP'
(字符串)而不是CURRENT_TIMESTAMP
生成的代码是:
```c#
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
模型构建器.Entity
{
entity.Property(e => e.Dt)
.HasDefaultValueSql("'CURRENT_TIMESTAMP'") // <-- 问题
.ValueGeneratedOnAddOrUpdate();
entity.Property(e => e.Ts)
.HasDefaultValueSql("'CURRENT_TIMESTAMP'") // <-- problem
.ValueGeneratedOnAddOrUpdate();
});
}
Trying to recreate the database with `myDbContext.Database.EnsureCreated()` will throw an exception
because the default value for the `timestamp` column is `'CURRENT_TIMESTAMP'`.
EFCore Log:
信息:Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 2.1.2-rtm-30932 使用提供程序“Pomelo.EntityFrameworkCore.MySql”初始化“TestDb”,选项:无
信息:Microsoft.EntityFrameworkCore.Database.Command[20101]
执行 DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
创建数据库TestDb_EFCore
;
失败:Microsoft.EntityFrameworkCore.Database.Command[20102]
执行 DbCommand 失败 (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
创建表TimestampTable
(
Id
int(11) NOT NULL AUTO_INCREMENT,
Ts
时间戳 NOT NULL DEFAULT 'CURRENT_TIMESTAMP',
Dt
日期时间 NULL DEFAULT 'CURRENT_TIMESTAMP',
约束PK_TimestampTable
主键 ( Id
)
);
Exception message:
MySql.Data.MySqlClient.MySqlException (0x80004005): 'Ts' 的默认值无效
Stack trace:
MySql.Data.MySqlClient.MySqlException (0x80004005): 'Ts' 的默认值无效 ---> MySql.Data.MySqlClient.MySqlException (0x80004005): 'Ts' 的默认值无效
在 MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync(IOBehavior ioBehavior) 在 C:\projects\mysqlconnector\src\MySqlConnector\Core\ResultSet.cs:line 42
在 MySql.Data.MySqlClient.MySqlDataReader.ActivateResultSet(ResultSet resultSet) 在 C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 74
在 MySql.Data.MySqlClient.MySqlDataReader.ReadFirstResultSetAsync(IOBehavior ioBehavior) 在 C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 299
在 MySql.Data.MySqlClient.MySqlDataReader.CreateAsync(MySqlCommand 命令,CommandBehavior 行为,ResultSetProtocol resultSetProtocol,IOBehavior ioBehavior) 在 C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 284
在 MySqlConnector.Core.TextCommandExecutor.ExecuteReaderAsync(String commandText, MySqlParameterCollection parameterCollection, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancelationToken) 在 C:\projects\mysqlconnector\src\MySqlConnector\Core\TextCommandExecutor.cs:line 37
在 C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlCommand.cs:line 261 中的 MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQueryAsync(IOBehavior ioBehavior, CancellationToken cancelationToken)
在 MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery() 在 C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlCommand.cs:line 62
在 Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues)
未处理的异常:MySql.Data.MySqlClient.MySqlException:“Ts”的默认值无效 ---> MySql.Data.MySqlClient.MySqlException:“Ts”的默认值无效
在 MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync(IOBehavior ioBehavior) 在 C:\projects\mysqlconnector\src\MySqlConnector\Core\ResultSet.cs:line 42
--- 内部异常堆栈跟踪结束 ---
在 MySql.Data.MySqlClient.MySqlDataReader.ActivateResultSet(ResultSet resultSet) 在 C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 74
在 MySql.Data.MySqlClient.MySqlDataReader.ReadFirstResultSetAsync(IOBehavior ioBehavior) 在 C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 299
在 MySql.Data.MySqlClient.MySqlDataReader.CreateAsync(MySqlCommand 命令,CommandBehavior 行为,ResultSetProtocol resultSetProtocol,IOBehavior ioBehavior) 在 C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 284
在 MySqlConnector.Core.TextCommandExecutor.ExecuteReaderAsync(String commandText, MySqlParameterCollection parameterCollection, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancelationToken) 在 C:\projects\mysqlconnector\src\MySqlConnector\Core\TextCommandExecutor.cs:line 37
在 C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlCommand.cs:line 261 中的 MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQueryAsync(IOBehavior ioBehavior, CancellationToken cancelationToken)
在 MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery() 在 C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlCommand.cs:line 62
在 Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection 连接,DbCommandMethod executeMethod,IReadOnlyDictionary 2 parameterValues)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary
2 参数值)
在 Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migrationCommands, IRelationalConnection 连接)
在 Microsoft.EntityFrameworkCore.Storage.RelationalDatabaseCreator.EnsureCreated()
在 CreateDb.Program.Main(String[] args) 在 /git/netcore-planet-garavot8-data/CreateDb/Program.cs:line 30
``
MySQL 版本: 5.7.20
操作系统: CentOS 7.4
Pomelo.EntityFrameworkCore.MySql 版本: 2.1.2
MySqlDatabaseModelFactory类中默认值的逻辑目前是基本的,因为它假定默认值是一个字符串。
将需要类型检查,即 varchar、int、enum 等,以确定是否需要引号(并在需要时使用转义)并遵循数据类型默认值中的规则。
已在 #896 中修复。
我发现下面的代码可以正常工作并在新版本发布之前避免错误。
```C#
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
模型构建器.Entity
{
entity.Property(e => e.Dt)
.HasDefaultValueSql("CURRENT_TIMESTAMP()")
.ValueGeneratedOnAddOrUpdate();
entity.Property(e => e.Ts)
.HasDefaultValueSql("CURRENT_TIMESTAMP()")
.ValueGeneratedOnAddOrUpdate();
});
}
``
最有用的评论
MySqlDatabaseModelFactory类中默认值的逻辑目前是基本的,因为它假定默认值是一个字符串。
将需要类型检查,即 varchar、int、enum 等,以确定是否需要引号(并在需要时使用转义)并遵循数据类型默认值中的规则。