使用LINQ(C#)操作SQL Server时TinyInt类型字段无法保存0整数问题
问题原因
该问题是Entity Framework/EF Core操作数据库时的常见配置类问题,主要有以下几类触发原因:
- 模型配置错误,
Alive字段被误设为自增列(Identity):EF插入自增列时会忽略代码传入的显式值,交由数据库自动生成值,若该字段设置了自增,初始插入值默认从1开始,会直接覆盖传入的0。 - 数据库端设置了默认值约束:如果
Alive字段在表结构中设置了默认值1,且EF配置中没有开启允许显式插入该字段的配置,插入时传入的0会被数据库默认值覆盖。 - 部分类隐藏了属性初始化逻辑:你贴出的是
partial类,若另一部分的partial类的构造函数、属性初始化器中给Alive默认赋值为1,会覆盖你传入的0值。 - 字段类型映射错误:若ORM配置中错误将
byte类型的Alive映射为数据库的bit类型,或者配置了值转换器将0/1做了反向转换,也会出现值变更的问题。 - 并发令牌配置错误:如果
Alive被错误配置为并发令牌,EF在插入时会自动生成该字段的值,覆盖传入的0。 - 自定义逻辑修改了属性值:如果全局配置了EF插入拦截器,或者重写了
SaveChanges方法统一处理实体字段,也可能存在将Alive的0值修改为1的逻辑。
解决步骤
你可以按照以下顺序排查修复:
检查实体模型配置,确认
Alive未被设置为自增:
若使用Fluent API配置,检查是否存在以下错误配置,直接删除对应配置项即可:modelBuilder.Entity<TestEntity>() .Property(p => p.Alive) .ValueGeneratedOnAdd(); // 或者UseIdentityColumn(),二者均为插入时自动生成值的配置,需要移除若使用数据注解配置,检查
Alive属性上是否加了[DatabaseGenerated(DatabaseGeneratedOption.Identity)]注解,移除该注解即可。检查数据库表的字段约束:
查看Alive字段是否设置了默认值1,如果不需要默认值可以直接删除默认约束;如果需要保留默认值,同时要支持显式插入0,需要在EF配置中添加以下配置,强制使用代码传入的值:modelBuilder.Entity<TestEntity>() .Property(p => p.Alive) .ValueGeneratedNever();检查partial类的其他部分:
查看同命名空间下的另一个TestEntity部分类,是否在构造函数、属性初始化器中给Alive赋值为1,如有需要移除该默认赋值,或者在初始化实体时显式覆盖该值。确认字段映射关系:
检查Alive属性的映射配置,确认没有配置错误的值转换器,且映射的数据库字段类型为tinyint而非bit,可通过以下配置显式指定类型避免自动映射错误:modelBuilder.Entity<TestEntity>() .Property(p => p.Alive) .HasColumnType("tinyint");排查全局修改逻辑:
检查是否配置了EF全局拦截器,或者重写的SaveChanges方法中存在修改Alive字段值的逻辑,调整对应逻辑即可。
内容的提问来源于stack exchange,提问作者TGod-Ajayi
相关产品推荐
相关产品推荐

