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

如何使用Predicate Builder实现字符串范围查询?

字符串范围查询实现方案(对标日期范围查询逻辑)

问题描述

现有以下可正常处理日期范围查询的表达式,请问如何用相同方式实现字符串范围查询?

附现有代码(含尝试的字符串查询逻辑,但存在问题):

expression = expression.And(x => x.ProductReceivedDate <= options.ProductReceivedDateEnd)
                    .And(x => x.ProductReceivedDate >= options.ProductReceivedDateStart);


if (!string.IsNullOrEmpty(options.PlateNumberFrom))
{
    expression = expression.And(x => x.InventoryNumber.CompareTo(options.PlateNumberFrom) >= string.Compare(x.InventoryNumber, options.PlateNumberFrom));

}

if (string.IsNullOrEmpty(options.PlateNumberTo))
    options.PlateNumberTo = options.PlateNumberFrom;

if (!string.IsNullOrEmpty(options.PlateNumberTo))
{
    expression = expression.And(x => x.InventoryNumber.CompareTo(options.PlateNumberTo) <= string.Compare(x.InventoryNumber, options.PlateNumberFrom));
}

修正后的实现方案

原字符串查询逻辑存在错误:嵌套调用的string.Compare(x.InventoryNumber, options.PlateNumberFrom)完全多余,且会导致比较逻辑混乱。我们可以直接对标日期查询的>=/<=逻辑,利用字符串CompareTo方法的返回值来实现范围过滤:

  • string.CompareTo()返回值规则:小于0表示当前字符串小于目标字符串;等于0表示相等;大于0表示当前字符串大于目标字符串
  • 要实现InventoryNumber >= PlateNumberFrom,只需判断CompareTo结果 >= 0
  • 要实现InventoryNumber <= PlateNumberTo,只需判断CompareTo结果 <= 0

修正后的代码如下:

// 保留原正确的日期范围查询逻辑
expression = expression.And(x => x.ProductReceivedDate <= options.ProductReceivedDateEnd)
                      .And(x => x.ProductReceivedDate >= options.ProductReceivedDateStart);

// 修正后的字符串范围查询逻辑
if (!string.IsNullOrEmpty(options.PlateNumberFrom))
{
    expression = expression.And(x => x.InventoryNumber.CompareTo(options.PlateNumberFrom) >= 0);
}

if (string.IsNullOrEmpty(options.PlateNumberTo))
    options.PlateNumberTo = options.PlateNumberFrom;

if (!string.IsNullOrEmpty(options.PlateNumberTo))
{
    expression = expression.And(x => x.InventoryNumber.CompareTo(options.PlateNumberTo) <= 0);
}

额外说明

如果业务需要忽略大小写、使用特定文化规则进行比较,可以改用string.Compare方法替换CompareTo,示例如下:

// 忽略大小写的起始值过滤
expression = expression.And(x => string.Compare(x.InventoryNumber, options.PlateNumberFrom, StringComparison.OrdinalIgnoreCase) >= 0);

// 忽略大小写的结束值过滤
expression = expression.And(x => string.Compare(x.InventoryNumber, options.PlateNumberTo, StringComparison.OrdinalIgnoreCase) <= 0);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 05:35:23