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

LINQ取模运算报float类型无效 如何转int实现千位四舍五入

报错根因

你当前使用的是会被ORM(EF/EF Core等)翻译为SQL语句执行的LINQ查询,代码中Math.Round(b.CostReproductionNew.Value)的返回值仍是映射为SQL浮点类型的float值,而SQL语法中float类型不支持%取模运算符,因此抛出类型不兼容的异常。

修复方案

方案1:数据库端显式类型转换(推荐,性能更好)

在参与取模运算前,将Math.Round处理后的浮点值显式转换为int类型,ORM会自动将这个转换翻译为SQL侧的整数类型转换逻辑,转换后即可正常执行取模运算。
修正后的代码如下:

allBuildings.Sum(b => 
    // 优先取大于0的BuildingOverride有效值
    b.BuildingOverride is > 0 
        ? b.BuildingOverride.Value
        : b.CostReproductionNew.HasValue 
            ? (
                // 显式转整数,解决float无法取模的问题
                int roundedVal = (int)Math.Round(b.CostReproductionNew.Value);
                roundedVal > 500
                    ? roundedVal % 1000 >= 500
                        ? roundedVal + 1000 - roundedVal % 1000
                        : roundedVal - roundedVal % 1000
                    : 500
            )
            : 0
);

如果你的开发环境不支持C# 7+的Lambda内变量声明,可以直接在每处参与运算的位置重复写(int)Math.Round(b.CostReproductionNew.Value)即可,逻辑完全一致。

方案2:内存侧计算(适配ORM版本不兼容转换的场景)

如果你的ORM版本对int类型转换的SQL翻译支持有问题,可以调用AsEnumerable()先把需要的字段加载到应用内存,后续计算完全走C#原生逻辑——C#原生支持float类型取模,不会触发SQL侧的类型报错。
代码如下:

allBuildings
    // 切换到内存计算
    .AsEnumerable()
    .Sum(b => 
        b.BuildingOverride is > 0 
            ? b.BuildingOverride.Value
            : b.CostReproductionNew.HasValue
                ? (
                    float roundedVal = Math.Round(b.CostReproductionNew.Value);
                    roundedVal > 500
                        ? roundedVal % 1000 >= 500
                            ? roundedVal + 1000 - roundedVal % 1000
                            : roundedVal - roundedVal % 1000
                        : 500
                )
                : 0
    );

注意:方案2会把目标表的相关字段全量加载到应用内存,如果表数据量很大,性能会明显低于方案1,优先选择显式类型转换的方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 19:48:21