【发布时间】:2010-01-29 21:57:43
【问题描述】:
如何在不调用帮助程序库 System.data.Linq.SqlClient 的情况下在我的 LINQ 查询中复制以下结果?
Where SqlMethods.Like(e.POSITION, "%A[FGL]7%") _
如果可能的话,我希望这个查询更纯粹是 LINQ。
【问题讨论】:
如何在不调用帮助程序库 System.data.Linq.SqlClient 的情况下在我的 LINQ 查询中复制以下结果?
Where SqlMethods.Like(e.POSITION, "%A[FGL]7%") _
如果可能的话,我希望这个查询更纯粹是 LINQ。
【问题讨论】:
编辑:基于我与 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% 起作用,因为模式本质上是转义的。换句话说,它只将其视为文字。
Where e.POSITION.Contains("A[FGL]7")
LINQ to SQL 将以这种方式转换 .NET 方法:
LIKE ...%
LIKE %...%
LIKE %...
【讨论】:
SqlMethods.Like 那样识别模式。我在发布后意识到了这一点,但保留它以显示差异。它们仅在您有固定字符串而不是模式时才有用。否则使用 VB Like 运算符或 SqlMethods.Like。
澄清:这个答案是在假设这不是一个 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。
【讨论】:
NotSupportedException,因为它“不支持对 SQL 的转换”。唯一可行的方法是在表上使用.AsEnumerable(),这通常是不可取的,因为整个表都会未经过滤。正则表达式很棒,但对于这种简单的情况,字符串类提供的方法就足够了,即使它不是 LINQ to SQL 查询。
string.Contains 是不够的。 OP 显然希望按模式过滤。
String.Contains 的看法。模式%A[FGL]7% 相当于您的正则表达式;即它出现在字符串中的任何位置,所以字符串确实“包含”它并且String.Contains 会起作用。
AG7 匹配正则表达式。 String.Contains 不使用模式,因此AG7 不包含 A[FGL]7。
大多数 LINQ 提供程序都支持 VB Like 运算符,它的作用几乎相同。在 C# 中,您可以通过 Microsoft.VisualBasic.CompilerServices.LikeOperator 的 LikeString 方法访问此功能:
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。)
【讨论】:
考虑这样的会员资料信息:
matches = matches.Union(memberDB.aspnet_Profile
.Where("it.PropertyValuesString Like @first", new ObjectParameter("first", "%<FirstName>%" + firstName + "%</FirstName>%"))
.Select(p => p.UserId));
【讨论】: