C#动态LINQ表达式验证咨询:求NuGet包或正则方案
.NET Framework 4.5 动态LINQ表达式有效性验证方案
需求明确
- 验证动态输入的LINQ字符串有效性(非开发者编写的固定表达式)
- 现有
ExpressionEvaluator存在误判:将无运算符连接的表达式、a.a这类错误成员访问的表达式判定为有效 DynamicExpresso.Core需提前指定参数,不符合动态场景需求- 目标:识别如
(a.AccountId==33||a.AccountId==2)&&(a.RoleId==1)的有效表达式,排除l.l.LinkId这类错误表达式
可行方案
1. NuGet包方案
NReco.Linq
兼容.NET Framework 4.5,无需提前定义参数类型,可直接解析并校验表达式语法,对错误的成员访问、无运算符连接的表达式能准确抛出异常。示例代码:
using NReco.Linq; var linqParser = new DynamicLinqParser(); try { // 尝试解析表达式,null表示不指定参数上下文 var validExpr = linqParser.ParseExpression("(a.AccountId==33||a.AccountId==2)&&(a.RoleId==1)", null); // 解析成功,表达式有效 } catch (ParseException ex) { // 解析失败,表达式存在语法错误 }
FastExpressionCompiler.LightExpression
兼容.NET Framework 4.5,可通过手动构建语法树检查逻辑,灵活处理动态场景。可以通过遍历表达式语法树节点,排查多层错误成员访问、无逻辑/比较运算符的无效表达式。
2. 正则表达式基础校验(仅做初步过滤)
正则只能覆盖基础语法场景,无法处理复杂嵌套或特殊情况,适合前置过滤。以下正则可匹配合法的单层成员访问+运算符组合的表达式,排除l.l.LinkId这类无运算符的错误表达式:
^(\s*\(\s*)?(([a-zA-Z_][a-zA-Z0-9_]*\.[a-zA-Z_][a-zA-Z0-9_]*\s*(==|!=|<|>|<=|>=)\s*(\d+|'[^']*'|true|false))(\s*(&&|\|\|)\s*([a-zA-Z_][a-zA-Z0-9_]*\.[a-zA-Z_][a-zA-Z0-9_]*\s*(==|!=|<|>|<=|>=)\s*(\d+|'[^']*'|true|false)))*(\s*\)\s*)?(\s*(&&|\|\|)\s*(\s*\(\s*)?(([a-zA-Z_][a-zA-Z0-9_]*\.[a-zA-Z_][a-zA-Z0-9_]*\s*(==|!=|<|>|<=|>=)\s*(\d+|'[^']*'|true|false))(\s*(&&|\|\|)\s*([a-zA-Z_][a-zA-Z0-9_]*\.[a-zA-Z_][a-zA-Z0-9_]*\s*(==|!=|<|>|<=|>=)\s*(\d+|'[^']*'|true|false)))*(\s*\)\s*)?)?$
说明:
- 仅允许单层成员访问(如
a.AccountId),排除多层嵌套的错误访问 - 支持比较运算符(
==/!=/</>/<=/>=)和逻辑运算符(&&/||) - 支持括号分组
- 过滤无运算符连接的单一无效表达式
内容的提问来源于stack exchange,提问作者Vadim T
相关产品推荐
相关产品推荐

