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

EF Core调用SumAsync对SQL Server float字段求和出现精度误差如何解决

问题根因

你遇到的精度误差是浮点数存储特性导致的:SQL Server的float类型和C#的double类型都属于二进制浮点数,无法精确存储所有十进制小数,40.005这类十进制小数在二进制存储时会产生微小的误差,累加后误差就会显现出来。

可行解决方案
  • 最优方案:调整字段类型为精确十进制类型
    如果你的业务场景涉及库存、金额等需要精确计算的数值,建议直接修改数据库字段和实体属性类型:
  1. 将SQL Server中Quantite字段从float改为decimal,可根据业务需求指定精度,比如decimal(18,3)即可满足3位小数的存储需求
  2. 将EF Core实体中Quantite属性的类型从double改为decimal
    修改后的求和代码不需要额外转换,即可得到精确结果:
public async Task<decimal> ObtenirTotalStockParSiteAsync(long siteId)
    => await Queryable.Where(snapshot => snapshot.SiteId == siteId)
        .SumAsync(snapshot => snapshot.Quantite)
        .ConfigureAwait(false);
  • 临时兼容方案:查询时转换为decimal再求和
    如果暂时无法修改数据库字段结构,可以在EF Core查询中将float值转换为decimal后再执行求和,该转换可被EF Core正确翻译为SQL层面的类型转换,避免累加误差:
public async Task<decimal> ObtenirTotalStockParSiteAsync(long siteId)
    => await Queryable.Where(snapshot => snapshot.SiteId == siteId)
        .SumAsync(snapshot => (decimal)snapshot.Quantite)
        .ConfigureAwait(false);
  • 应急修复方案:对返回结果做精度舍入
    如果不想修改现有代码的返回值类型,可以在拿到求和后的double结果后,按业务需要的小数位做四舍五入:
public async Task<double> ObtenirTotalStockParSiteAsync(long siteId)
    => Math.Round(await Queryable.Where(snapshot => snapshot.SiteId == siteId)
        .SumAsync(snapshot => snapshot.Quantite)
        .ConfigureAwait(false), 3);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 00:39:03