【问题标题】:Using LINQ Contains versus SqlMethods.Like使用 LINQ Contains 与 SqlMethods.Like
【发布时间】:2010-01-29 21:57:43
【问题描述】:

如何在不调用帮助程序库 System.data.Linq.SqlClient 的情况下在我的 LINQ 查询中复制以下结果?

Where SqlMethods.Like(e.POSITION, "%A[FGL]7%") _

如果可能的话,我希望这个查询更纯粹是 LINQ。

【问题讨论】:

    标签: asp.net vb.net linq


    【解决方案1】:

    编辑:基于我与 Lette 的 cmets,我最初错过了 SqlMethods.Like 支持的模式匹配。

    您的查询看起来像 VB,因此您实际上可以直接使用 Like operator,但您需要将 % 替换为星号 *

    Where e.POSITION Like "*A[FGL]7*" _
    

    如果您使用的是 C#,则需要在调用 AsEnumerable() 后使用 Lette's suggestion 将数据放入内存(可能首先根据任何其他条件进行过滤然后调用正则表达式进一步过滤)或关注Ruben's suggestion

    我在下面提到的方法不像 SqlMethods.Like 方法那样 100% 起作用,因为模式本质上是转义的。换句话说,它只将其视为文字。


    只需在其上使用常规 String.Contains 方法:
    Where e.POSITION.Contains("A[FGL]7")
    

    LINQ to SQL 将以这种方式转换 .NET 方法:

    • 文本。StartsWith(...) = LIKE ...%
    • 文本。包含(...) = LIKE %...%
    • 文本。EndsWith(...) = LIKE %...

    【讨论】:

    • 这是一个 Linq-To-Sql 问题吗?如果是这样,你可能是对的。我的印象是 OP 想要一个“纯”的 Linq 解决方案。
    • @Lette 我相信是这样,因为 OP 使用的是仅在 LINQ to SQL (msdn.microsoft.com/en-us/library/bb355235.aspx) 中受支持的 SqlMethods 类。
    • 上述 String.Contains 方法不返回任何结果。
    • @mmcglynn 是的,它不会像SqlMethods.Like 那样识别模式。我在发布后意识到了这一点,但保留它以显示差异。它们仅在您有固定字符串而不是模式时才有用。否则使用 VB Like 运算符或 SqlMethods.Like
    【解决方案2】:

    澄清:这个答案是在假设这不是一个 LINQ to SQL 问题的情况下编写的。如果是,请转到其他答案。

    为此,您必须模仿 SQL 中的 Like 运算符。在您的情况下,这可能最好使用正则表达式来完成。

    这是一个例子:

    using System.Text.RegularExpressions;
    
    ...
    
    Regex regex = new Regex("^.*A[FGL]7.*$");
    
    // assuming that 'e' is a sequence of elements of type Foo
    IEnumerable<Foo> results = e.Where(foo => regex.IsMatch(foo.POSITION));
    

    现在应该根据您的需要过滤results

    【讨论】:

    • 请务必注意,在 LINQ to SQL 中使用正则表达式会抛出 NotSupportedException,因为它“不支持对 SQL 的转换”。唯一可行的方法是在表上使用.AsEnumerable(),这通常是不可取的,因为整个表都会未经过滤。正则表达式很棒,但对于这种简单的情况,字符串类提供的方法就足够了,即使它不是 LINQ to SQL 查询。
    • @Ahmad - 您必须记住,这个答案是在假设它 不是 一个 linq-to-sql 问题的情况下编写的。在这种情况下,string.Contains 是不够的。 OP 显然希望按模式过滤。
    • 我完全同意,我并不是要攻击你的答案。如果这是 L2S,那么我的评论是有效的。否则,您的解决方案是完全有效的。但是,我不同意你对String.Contains 的看法。模式%A[FGL]7% 相当于您的正则表达式;即它出现在字符串中的任何位置,所以字符串确实“包含”它并且String.Contains 会起作用。
    • @Ahmad - 没有冒犯。我只是说AG7 匹配正则表达式。 String.Contains 不使用模式,因此AG7包含 A[FGL]7
    • 哇!我完全错过了 [FGL] 课程及其与 LIKE 的相关性。你是对的,我提到的方法没有考虑到这一点(更新了我的回复)并且不会识别模式。我还有 45 分钟没有投票权,所以我会拒绝。到那时+1。很好的收获:)
    【解决方案3】:

    大多数 LINQ 提供程序都支持 VB Like 运算符,它的作用几乎相同。在 C# 中,您可以通过 Microsoft.VisualBasic.CompilerServices.LikeOperatorLikeString 方法访问此功能:

    using Microsoft.VisualBasic;
    using Microsoft.VisualBasic.CompilerServices;
    
    ...
    
    where LikeOperator.LikeString(e.POSITION, "*A[FGL]7*", CompareMethod.Text)
    

    请注意 VB 的 Like 使用的语法与 SQL 的 Like 略有不同;值得注意的是,它使用*? 而不是%_。 (不过,LINQ to SQL 将此 VB 语法转换为 SQL 语法。)

    (别忘了参考 Microsoft.VisualBasic.dll。)

    【讨论】:

      【解决方案4】:

      考虑这样的会员资料信息:

      matches = matches.Union(memberDB.aspnet_Profile
                          .Where("it.PropertyValuesString Like @first", new ObjectParameter("first", "%<FirstName>%" + firstName + "%</FirstName>%"))
                          .Select(p => p.UserId));
      

      【讨论】:

        猜你喜欢
        • 2017-03-31
        • 1970-01-01
        • 1970-01-01
        • 2015-02-04
        • 2011-08-07
        • 1970-01-01
        • 2010-09-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多