【问题标题】:DynamicLINQ - Escaping double quotes inside stringsDynamicLINQ - 在字符串中转义双引号
【发布时间】:2014-04-21 15:05:44
【问题描述】:

我正在尝试使用 DynamicLINQ 库创建一个动态过滤系统。当您执行以下操作时,我的一切都会顺利进行:查找名字是 Bob 的人:

Context.Users.Where("FirstName == \"Bob\"");

但是当我想做的时候遇到了问题:查找名字是“Bob”的人(其中 Bob 存储在数据源中的双引号中)。

我尝试了一些不同的方法,包括转义转义的双引号和其他一些变体:

Context.Users.Where("FirstName == \"\\\"Bob\\\"\"");
// or as a literal for readability
Context.Users.Where(@"FirstName == ""\""Bob\""""");
// From comments below
Context.Users.Where("FirstName == \"\"Bob\"\"");

这些都不起作用。任何帮助将不胜感激。

谢谢。

EDIT - 我现在只是在处理生成的字符串。实际的字符串是从模型生成的。

【问题讨论】:

  • 你能用string.ReplaceRegEx吗?
  • 也许是这个? "FirstName == \"\"Bob\"\""
  • @HamletHakobyan - 不幸的是,这也不起作用。
  • @DJKRAZE - 不确定这有什么帮助?他们最后仍然会产生一个字符串。
  • @RichardRout 你可以尝试像这样Context.Users.Where("FirstName == @0", "\"Bob\""); 参数化你的查询

标签: c# dynamic-linq


【解决方案1】:

如果你想在子句中使用一些带有特殊符号的特定字符串,那么更好的方法,我认为,使用像这样的参数化形式

Context.Users.Where("FirstName == @0", "\"Bob\"");

【讨论】:

    【解决方案2】:

    我的想法是你不能像你写的那样使用.Where() 来进行动态 linq 评估。原因是Where() 不了解FirstName 是什么,并且从未打算做动态Linq 表达式。您将使用 where 如下所示 .Where( x => x.FirstName == "\"Bob\""); 肯定会起作用。

    一个好的开始是使用 ScottGu 博客上的现有库,如下所示:

    http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

    他下载了一个代码,可以完成你所描述的一切。消化这个库需要一点时间,但我已经在一个项目中使用它并且效果很好。你需要对 Lambdas 有所了解,才能走得更远。

    希望这会有所帮助 :) 好问题,我去过那里并做到了。找到这个解决方案很棘手。

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 编辑

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    查看 Dynamic.cs:

    第 2123 行,方法ParseToken() 中存在以下代码。

                case '"':
                case '\'':
                    char quote = ch;
                    do
                    {
                        NextChar();
                        while (textPos < textLen && ch != quote) NextChar();
                        if (textPos == textLen)
                            throw ParseError(textPos, Res.UnterminatedStringLiteral);
                        NextChar();
                    } while (ch == quote);
                    t = TokenId.StringLiteral;
                    break;
    

    这个解析器似乎在做的是:当它读取[""Bob""] 中的第二个" 时,它返回一个空字符串文字,认为它找到了字符串文字的结尾,然后它会解析一个标识符@987654330 @ 然后是另一个空字符串文字。不知何故,您将不得不修改解析器以查找 "" 作为令牌。

    也许在第 766 行的ParseComparison() 中,您可以设计一种方法来查找空字符串文字,后跟一个标识符,然后是另一个空字符串文字。 ???

    简单的解决方案是将 " 替换为 null,因为重写解析器看起来需要付出很大的努力。

    【讨论】:

    • 显然他还没有使用 LINQ,否则他的代码甚至无法编译,更不用说运行了。他正在使用动态 LINQ 库,正如他在他的问题中所说的那样。
    • 感谢@Servy - 如前所述,我正在使用 DynamicLinq 库。将更新问题以更清楚。
    • 好的,抱歉,我没有意识到这一点。我使用它有点不同,并围绕它编写了一个规则引擎。另一个想法。在 Dynamic.cs 中有枚举 TokenId。在我的版本中,我没有看到他们正在解析“。这让我认为它没有考虑到这种用法。您可以按照 DJ KRAZE 所说的那样做,并在评估之前从字符串中删除所有“。
    • 另一个想法是在代码中的 NextToken()、ParsePrimaryStart()、ParseStringLiteral 等处设置断点,在代码中使用 TokenId.StringLiteral 以查看它如何解析您的表达式。从那里您应该能够看到如何修改库。一旦找到正确的位置,您就可以修改构建 lamda 的方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-06
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多