DevExpress升级后GetOracleWhere方法加引号致Oracle SQL错误求助
DevExpress升级后Oracle查询引号问题解决方案
代码片段
if (!String.IsNullOrEmpty(filterColumns)) { filterColumns = filterColumns.Replace("[", "[lower(").Replace("]", ")]"); CriteriaOperator op = CriteriaOperator.Parse(filterColumns); string filter = String.Empty; if (dbUtils.DbType == 1) { filter = CriteriaToWhereClauseHelper.GetOracleWhere(op, false); filter = filter.ToLower(); } }
问题描述
这段C#代码在旧版DevExpress中运行正常,升级后GetOracleWhere方法生成的查询会给lower(templatename)强制添加双引号,导致Oracle SQL报错。生成的SQL示例如下:
SELECT COUNT(*) dataCount FROM (SELECT r.* FROM rmrtemplate r WHERE templatename IS NOT NULL AND (instr("lower(templatename)", '0022') > 0)) tmptable
问题核心:被双引号包裹的"lower(templatename)"会被Oracle识别为字符串而非SQL函数,进而抛出无效标识符错误,问题由filter = CriteriaToWhereClauseHelper.GetOracleWhere(op, false);这一行引发。
当前GetOracleWhere的可用重载:
public static string GetOracleWhere(CriteriaOperator op); public static string GetOracleWhere(CriteriaOperator op, bool forceQuotesOnOperandProperties); public static string GetOracleWhere(CriteriaOperator op, Func<OperandProperty, string> propertyFormatter);
曾尝试用正则和字符串替换移除引号,但未生效:
filter = Regex.Replace(filter, "\"(lower\\(templatename\\))\"", "$1"); // 尝试移除lower(templatename)周围的引号 filter = filter.Replace("\"", ""); // 尝试移除所有剩余引号
可行解决办法
方法1:使用带propertyFormatter的重载(推荐)
利用第三个重载自定义属性格式化逻辑,从根源上避免给包含SQL函数的表达式添加引号:
if (dbUtils.DbType == 1) { filter = CriteriaToWhereClauseHelper.GetOracleWhere(op, operandProperty => { // 若属性名称包含lower(,直接返回原表达式,不添加引号 if (operandProperty.PropertyName.Contains("lower(")) { return operandProperty.PropertyName; } // 正常属性按需处理,这里保留默认加引号的逻辑(可根据实际调整) return $"\"{operandProperty.PropertyName}\""; }); filter = filter.ToLower(); }
方法2:修正正则替换逻辑
如果坚持用字符串替换,调整正则表达式匹配通用的lower(...)格式,同时忽略大小写:
// 匹配所有被双引号包裹的lower(...)表达式,忽略大小写 filter = Regex.Replace(filter, "\"(lower\\([^)]+\\))\"", "$1", RegexOptions.IgnoreCase); // 移除剩余不必要的引号 filter = filter.Replace("\"", "");
方法3:用DevExpress API构建函数表达式
避免手动拼接lower(字符串,改用FunctionOperator构建函数条件,让DevExpress正确识别SQL函数:
if (!String.IsNullOrEmpty(filterColumns)) { // 示例:构建lower(templatename)包含'0022'的查询条件 var property = new OperandProperty("templatename"); var lowerFunction = new FunctionOperator(FunctionOperatorType.Lower, property); var criteria = new FunctionOperator(FunctionOperatorType.Contains, lowerFunction, "0022"); string filter = String.Empty; if (dbUtils.DbType == 1) { filter = CriteriaToWhereClauseHelper.GetOracleWhere(criteria); filter = filter.ToLower(); } }
内容的提问来源于stack exchange,提问作者Natnael Haile
相关产品推荐
相关产品推荐

