使用Dynamic LINQ求和时将int转为long抛出算术溢出异常
解决Dynamic LINQ多整数列求和的算术溢出问题
问题场景
用Dynamic LINQ对多个int类型列求和时,若总和超出int.MaxValue,会触发算术溢出异常:
- 外层异常:
System.Data.Entity.Core.EntityCommandExecutionException - 内部异常:
System.Data.SqlClient.SqlException,提示“将表达式转换为int类型时发生算术溢出”
复现场景:3个Employee对象的Test字段设为int.MaxValue,执行以下代码触发异常:
context.Employees.GroupBy(w=>true).Select("new(SUM(Test) as Test,SUM(Id) as Id)").ToDynamicList().FirstOrDefault();
可行解决方案
方案1:修正CAST转换语法
之前的转换写法不符合Dynamic LINQ的语法规则,正确的做法是在SUM内部先将字段转换为更大的数值类型,比如long或decimal:
// 转换为long类型求和 context.Employees.GroupBy(w=>true) .Select("new(SUM(CAST(Test as long)) as Test, SUM(Id) as Id)") .ToDynamicList().FirstOrDefault(); // 或者转换为decimal类型求和 context.Employees.GroupBy(w=>true) .Select("new(SUM(CAST(Test as decimal)) as Test, SUM(Id) as Id)") .ToDynamicList().FirstOrDefault();
方案2:用强类型结果约束转换
定义一个接收求和结果的类,通过强类型Select重载让Dynamic LINQ自动匹配类型:
// 定义结果类,Test字段用long避免溢出 public class SumResult { public long Test { get; set; } public int Id { get; set; } } // 使用强类型Select context.Employees.GroupBy(w=>true) .Select<SumResult>("new(SUM(Test) as Test, SUM(Id) as Id)") .FirstOrDefault();
失败原因分析
- 你之前尝试的
SUM(Convert(decimal, Test))不是Dynamic LINQ支持的语法,它更兼容SQL风格的CAST(字段 as 类型)写法。 - Dynamic LINQ默认会沿用原字段的int类型推导SUM结果,当总和超出int范围时就会溢出,必须显式转换或通过目标类型约束修正。
额外提示
如果是搭配EF Core使用,确保Dynamic LINQ版本为最新,旧版本对EF Core的类型转换支持存在缺陷,升级后能解决部分语法解析问题。
内容的提问来源于stack exchange,提问作者ADB
相关产品推荐
相关产品推荐

