ASP.NET 8+EF Core+MySQL下解决Timestamp无默认值乐观并发错误
解决MySQL下EF Core Timestamp字段无默认值的问题
原因分析
EF Core的[Timestamp]特性默认适配SQL Server的rowversion类型,但MySQL没有该类型。当前仅配置了值生成策略,未在数据库层面为TIMESTAMP字段设置默认值,导致插入数据时数据库抛出无默认值的错误。
具体解决方案
方案1:适配MySQL TIMESTAMP自动生成规则
修改实体类和DbContext配置,让MySQL自动处理TIMESTAMP的生成与更新:
更新实体类:
保留[Timestamp]用于并发检查,同时指定MySQL对应的字段类型:public class Order { public long Id { get; set; } // 其他属性 [Timestamp] [Column(TypeName = "timestamp")] public byte[] Timestamp { get; set; } }调整DbContext配置:
配置数据库层面的默认值,并标记为并发令牌:builder.Entity<Order>() .Property(c => c.Timestamp) .HasColumnType("timestamp") .HasDefaultValueSql("CURRENT_TIMESTAMP") .ValueGeneratedOnAddOrUpdate() .IsConcurrencyToken();HasDefaultValueSql("CURRENT_TIMESTAMP"):让MySQL在插入数据时自动生成当前时间戳IsConcurrencyToken():显式标记该字段为并发检查令牌,与[Timestamp]特性配合实现并发控制
方案2:配置更新时自动刷新时间戳
如果需要在更新订单时自动刷新Timestamp值,可添加ON UPDATE规则(MySQL 8.0+支持):
builder.Entity<Order>() .Property(c => c.Timestamp) .HasColumnType("timestamp") .HasDefaultValueSql("CURRENT_TIMESTAMP") .HasComputedColumnSql("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP") .ValueGeneratedOnAddOrUpdate() .IsConcurrencyToken();
方案3:手动初始化Timestamp(临时应急方案)
若暂时无法修改数据库配置,可在插入前手动赋值:
var order = new Order { // 其他属性赋值 Timestamp = BitConverter.GetBytes(DateTime.UtcNow.Ticks) }; _dbContext.Orders.Add(order); await _dbContext.SaveChangesAsync();
此方法无法利用数据库自动更新机制,并发检查可能失效,仅作为临时解决手段。
注意事项
- 修改配置后需重新生成并应用迁移:
Add-Migration UpdateTimestampConfig Update-Database - 确保使用的MySQL版本支持
CURRENT_TIMESTAMP和ON UPDATE语法(MySQL 5.6及以上版本均可)
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

