使用 toLowerSay 筛选一组值的导航属性

Filtering on navigation properties for a set of value with toLowerCase

本文关键字:一组 导航 属性 toLowerSay 筛选 使用      更新时间:2023-09-26

我有这个JayData查询(可以在JSLQ操场上检查):

northwind.Products
  .filter( function( product ) {
    return  product.ProductName.toLowerCase() in ['tofu'];
  } )
  .toArray( function( products ) {
    console.dir( products );
  } );

由于某些未知原因,此查询生成不正确的筛选器表达式:http://services.odata.org/Northwind/Northwind.svc/Products?$filter=(tolowerProductName%20eq%20%27tofu%27)&$callback=parent.handleJSONP_21&$format=json

我在上面用粗体突出显示了不正确的参数。

所以你可以看到我们有 tolowerProductName,但它应该是 tolower(ProductName),所以正确的过滤器查询应该看起来像这样:http://services.odata.org/Northwind/Northwind.svc/Products?$filter=%28tolower%28ProductName%29%20eq%20%27tofu%27%29&$callback=parent.handleJSONP_21&$format=json

有人知道解决方法吗?

更新:仅当我将 toLowerCase 与"in [array]"一起使用时才会出现问题,因此例如此查询工作正常:

northwind.Products
  .filter( function( product ) {
    return  product.ProductName in ['Tofu'];
  } )
  .toArray( function( products ) {
    console.dir( products );
  } );

这个带有toLowerCase的查询也可以正常工作:

northwind.Products
  .filter( function( product ) {
    return  product.ProductName.toLowerCase() == 'Tofu';
  } )
  .toArray( function( products ) {
    console.dir( products );
  } );

谢谢!

您是否尝试过将该表达式设置为变量,然后在['豆腐']中检查它?

我发现不正确的过滤器表达式会产生以下代码行(对于带有"in"运算符的查询):

context.data = temp + context.data.replace(/'(/g, '').replace(/')/g, '');

oDataProvider 中的第 1542 行.js

我用以下代码替换了它:

context.data = temp + context.data;

现在一切都按预期工作。也许我在此修复中引入了其他问题,但至少它在我的查询中按预期工作。

所以 VisitSimpleBinaryExpression 函数现在看起来像这样:

VisitSimpleBinaryExpression: function (expression, context) {
        context.data += "(";
        //TODO refactor!!!
        if (expression.nodeType == "in") {
            Guard.requireType("expression.right", expression.type, $data.Expressions.ConstantExpression);
            var paramValue = expression.right.value;
            if (!paramValue instanceof Array) { Guard.raise(new Exception("Right to the 'in' operator must be an array value")); }
            var result = null;
            var orResolution = { mapTo: "or", dataType: "boolean", name: "or" };
            var eqResolution = { mapTo: "eq", dataType: "boolean", name: "equal" };
            paramValue.forEach(function (item) {
                var idValue = item;
                var idCheck = Container.createSimpleBinaryExpression(expression.left, idValue,
                    $data.Expressions.ExpressionType.Equal, "==", "boolean", eqResolution);
                if (result) {
                    result = Container.createSimpleBinaryExpression(result, idCheck,
                    $data.Expressions.ExpressionType.Or, "||", "boolean", orResolution);
                } else {
                    result = idCheck;
                };
            });
            var temp = context.data;
            context.data = '';
            this.Visit(result, context);
            //context.data = temp + context.data.replace(/'(/g, '').replace(/')/g, '');
            context.data = temp + context.data;
        } else {
            this.Visit(expression.left, context);
            context.data += " ";
            context.data += expression.resolution.mapTo;
            context.data += " ";
            this.Visit(expression.right, context);
        };
        context.data += ")";
    },