如何在LINQ中仅过滤查询的数字部分并匹配传入数值
问题分析与解决方案
原代码无法返回数据的核心问题如下:
- 分割符错误:你用
_作为分隔符,但实际数据是用-分隔(如C-1789),导致无法正确提取数字部分 - 未处理
numerId为NULL/空值的情况,直接调用Trim()会引发异常 SqlFunctions.IsNumeric的判断逻辑不符合需求,且数字提取逻辑不严谨
以下是修正后的代码,同时优化了数字提取的鲁棒性:
public async Task<IEnumerable<Transaction_DTO>> GetTransactionDetailByNumber(string number) { var query = from rm in model.table1 join sy in model.table2 on rm.index equals sy.index into syJoin from sy in syJoin.DefaultIfEmpty() // 先处理NULL/空值,避免Trim引发空引用异常 let cleanedNumerId = string.IsNullOrEmpty(rm.numerId) ? string.Empty : rm.numerId.Trim() // 查找最后一个'-'的位置,适配多分隔符场景 let lastDashIndex = SqlFunctions.Reverse(SqlFunctions.CharIndex("-", SqlFunctions.Reverse(cleanedNumerId))) // 提取分隔符后的内容,无分隔符则取原字符串 let rawNumericPart = lastDashIndex > 0 ? SqlFunctions.Substring(cleanedNumerId, lastDashIndex + 1, cleanedNumerId.Length - lastDashIndex) : cleanedNumerId // 过滤所有非数字字符,确保最终得到纯数字串 let numericPart = SqlFunctions.Replace(SqlFunctions.Replace(rawNumericPart, "-", ""), " ", "") where !string.IsNullOrEmpty(numericPart) && numericPart == number orderby rm.TransDate descending select new Transaction_DTO { Col1 = rm.Col1, }; return await query.ToListAsync(); }
关键优化说明
- 空值防护:通过
string.IsNullOrEmpty提前处理numerId的NULL/空值情况,避免后续操作报错 - 适配实际分隔符:将分割符改为
-,匹配你给出的C-1789、NFP-9785这类数据格式 - 鲁棒的数字提取:通过
Reverse+CharIndex定位最后一个-,确保提取到最末尾的数字部分;再通过Replace过滤掉残留的非数字字符 - 简化匹配逻辑:去掉
SqlFunctions.IsNumeric,直接判断提取后的纯数字串是否与传入参数一致,避免IsNumeric的误判问题
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

