如何解决EntityFramework Core操作SQL Server Temporal表插入报错问题
错误原因
Scaffold-DbContext 逆向生成实体时,默认无法识别SQL Server系统版本化(临时)表的GENERATED ALWAYS列,生成的SysStartTime、SysEndTime属性会被判定为普通可写字段。EF Core执行插入操作时,会将这两个DateTime类型属性的默认值(0001/1/1 0:00:00)作为显式值提交到数据库,违反了系统版本化列不允许手动赋值的规则,因此抛出异常。
你直接执行SQL脚本可以插入成功,是因为你没有在INSERT语句中显式指定这两个列,数据库会自动填充对应值,符合规则。
解决方法
只需在DbContext配置中标记这两个列由数据库生成即可,有两种常用配置方式:
方式1:数据注解标注
修改person实体类,给两个系统时间列添加[DatabaseGenerated]注解:
using System.ComponentModel.DataAnnotations.Schema; public partial class person { public int ID { get; set; } public string NAME { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime SysStartTime { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime SysEndTime { get; set; } }
建议单独新建partial类文件写注解,避免后续重新执行Scaffold命令时覆盖修改内容。
方式2:Fluent API配置
在myDBContext类的OnModelCreating方法中添加配置:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<person>(e => { // EF Core 6及以上版本可以直接调用IsTemporal()方法,自动适配系统版本化表规则 e.ToTable(tb => tb.IsTemporal()); // 低于EF Core 6版本可以单独配置两个字段的生成规则 // e.Property(p => p.SysStartTime).ValueGeneratedOnAddOrUpdate(); // e.Property(p => p.SysEndTime).ValueGeneratedOnAddOrUpdate(); }); }
配置完成后EF Core执行插入、更新操作时会自动忽略这两个字段的赋值,由数据库生成对应值,即可正常执行操作。
内容的提问来源于stack exchange,提问作者SeReGa
相关产品推荐
相关产品推荐

