You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用EF Core 7无法将SQL Server数据库decimal字段设为0的问题

问题原因与解决方案

核心原因

你用Attach方法将新创建的TransactionClass实体附加到上下文时,该实体的Percentage字段默认值是0(decimal类型的默认值就是0,代码里的= default!实际等价于0)。之后你把它设置为0,EF Core的变更追踪系统会判定这个字段的值没有发生变化,因此不会生成更新该字段的SQL语句,数据库里的值自然不会被修改。

而当你设置大于0的值时,因为初始默认值是0,新值和初始值存在差异,变更追踪能检测到变化,所以会正常生成更新语句。

解决方法

有三种可行的解决方式:

方法1:手动标记字段为已修改

在设置Percentage的值后,显式告知EF Core该字段已修改,强制生成更新语句:

public bool UpdateClasses(Accounting.Shared.Dtos.Request.Transaction.Class.UpdateDto transactionClass)
{
    using (accountingContext db = new())
    {
        var updateClass = new TransactionClass { TransactionClassId = transactionClass.TransactionClassId };
        db.TransactionClasses.Attach(updateClass);
        updateClass.Name = transactionClass.Name;
        updateClass.Percentage = 0;
        // 手动标记字段为已修改
        db.Entry(updateClass).Property(x => x.Percentage).IsModified = true;
        db.SaveChanges();
    }

    return true;                
}

方法2:先查询实体再修改

如果业务场景允许,先从数据库加载目标实体,再修改字段值,这样EF Core能准确追踪到值的变化:

public bool UpdateClasses(Accounting.Shared.Dtos.Request.Transaction.Class.UpdateDto transactionClass)
{
    using (accountingContext db = new())
    {
        var updateClass = db.TransactionClasses.FirstOrDefault(x => x.TransactionClassId == transactionClass.TransactionClassId);
        if (updateClass != null)
        {
            updateClass.Name = transactionClass.Name;
            updateClass.Percentage = 0;
            db.SaveChanges();
        }
    }

    return true;                
}

方法3:调整实体默认值(不推荐)

把实体中Percentage的默认值改成非0数值,比如:

public decimal Percentage { get; set; } = -1;

但这种方法会引入逻辑混淆,只有在特殊场景下才考虑使用,优先选择前两种方法。

补充说明

  • Name字段能正常更新,是因为实体初始化时Name为String.Empty,而你设置的是传入的transactionClass.Name(通常不是空字符串),变更追踪能检测到这个差异,所以会生成更新语句。
  • 数据库的默认值仅在插入新记录时生效,更新操作不会自动调用默认值,必须显式处理更新逻辑。

内容的提问来源于stack exchange,提问作者Musaffar Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 19:50:25