如何使用LINQ对指定列求和并包含当前数据完成安全校验
问题1:原有LINQ查询的正确性分析
- 语法存在错误:
- 方法声明返回
Task<bool>,但现有代码是同步实现,没有异步操作和await关键字,返回值类型不匹配 - 代码大括号位置错误,
checkRsult变量定义在方法的闭合大括号之后,作用域非法,外部无法访问
- 方法声明返回
- 逻辑冗余:不需要投影匿名类再求和,可直接对
AmountToTransfer字段求和,简化写法 - 潜在边界问题:如果数据库存储的
Created字段是UTC时间,用DateTime.Today(本地时间)计算统计区间会出现误差,建议统一用UTC时间计算时间范围 - 空集合兼容:EF/EF Core中对符合条件的空记录集合调用
Sum()/SumAsync()会默认返回0,不会抛出空引用异常,这部分逻辑是正常的
问题2:单次查询完成包含当前金额的求和实现
完全可以,本身对数据库的求和就是单次查询,当前传入的cust.Amount是内存常量,直接追加在求和结果后即可,不会产生额外的数据库请求,优化后的完整代码如下:
public async Task<bool> SecurityCheck(CustomerData cust) { // 仅发起1次数据库查询,求和后直接累加当前金额 var totalAmount = await dbContext.CustomerModel .Where(x => x.CustomerReference == cust.CustomerReference && x.Created >= DateTime.UtcNow.Date.AddMonths(-3)) .SumAsync(x => x.AmountToTransfer) + cust.Amount; if (totalAmount > 250000) { return false; } // 此处添加模型入库逻辑 return true; }
注意:不要把
cust.Amount写到SumAsync的选择器表达式中,否则会给每一条历史转账记录都累加一次当前金额,导致统计结果完全错误。
内容的提问来源于stack exchange,提问作者moris62
相关产品推荐
相关产品推荐

