C#如何查找最接近指定日期的记录 解决TimeSpan类型不支持报错
需求说明
需要对照GivenDate字段,匹配与DateToCompare日期最接近的ApmaksasApmers(引用值)对应数值。
示例场景:
DateToCompare取值为01.01.2022、01.01.2021,GivenDate取值为01.03.2022时,预期获取01.01.2022对应的记录值。
当前实现代码
vm.ApmaksasApmērs.LookupSource = _nolasītMaksājumusQuery.Nolasīt() .OrderBy(x => x.DateToCompare.Value > vm.GivenDate.Value ? vm.GivenDate.Value - x.DateToCompare.Value : x.DateToCompare.Value - vm.GivenDate.Value) .Select(x => new KeyValuePair<Guid?, string>(x.Id, x.ApmaksasApmērs +" (" + x.PersonasLīdzmaksājumsProcentos + "%)".ToString())) ;
运行报错信息
Name:[ApmaksasApmērs],Type:[ReferenceValue],Message:[Don't currently support idents of type TimeSpan]
问题原因与优化方案
报错根因
原排序逻辑中直接对两个DateTime类型值做减法,返回值为TimeSpan类型,当前使用的数据查询提供器(ORM)未实现TimeSpan类型的表达式翻译能力,无法将该排序逻辑转换为可执行的查询语句,因此抛出类型不支持的错误。
优化实现
优化点如下:
- 提前过滤
DateToCompare为空的无效记录,避免空引用异常 - 排序时使用日期
Ticks(长整型时间戳)的差值绝对值计算时间差,数值类型可被所有查询提供器正常识别翻译,解决TimeSpan不支持的问题 - 增加一级排序规则,优先匹配不晚于
GivenDate的最近记录,完全贴合示例中的业务匹配逻辑 - 简化字符串拼接写法,去掉无意义的
ToString()调用
优化后代码:
var targetDate = vm.GivenDate.Value; vm.ApmaksasApmērs.LookupSource = _nolasītMaksājumusQuery.Nolasīt() .Where(x => x.DateToCompare.HasValue) // 优先取日期不晚于目标日期的记录 .OrderBy(x => x.DateToCompare.Value > targetDate ? 1 : 0) // 按时间差绝对值升序,取最接近的日期 .ThenBy(x => Math.Abs(x.DateToCompare.Value.Ticks - targetDate.Ticks)) .Select(x => new KeyValuePair<Guid?, string>( x.Id, $"{x.ApmaksasApmērs} ({x.PersonasLīdzmaksājumsProcentos}%)" ));
内容的提问来源于stack exchange,提问作者Renārs Abeļūns
相关产品推荐
相关产品推荐

