【问题标题】:LINQ to SQL WildcardsLINQ to SQL 通配符
【发布时间】:2010-06-08 18:27:59
【问题描述】:

如何在我的 LINQ To SQL lambda 表达式中构建通配符?

这是我目前拥有的:

var query = from log in context.Logs select log;
foreach (string filter in CustomReport.ExtColsToFilter)
{
    string tempFilter = filter;
    query = query.Where(Log => Log.FormattedMessage.Contains(tempFilter));
}

在我尝试在过滤器字符串中传递通配符之前,这一切正常。我正在尝试SqlMethods.Like(),但无济于事。

上面的过滤器如下所示:"<key>NID</key><value>mcass</value>"

我希望能够通过这样的过滤器:"<key>NID</key><value>%m%</value>"

【问题讨论】:

  • SqlMethods.Like 应该可以工作。试一试会有什么结果?
  • @Thorarin 生成的 SQL 与 .Contains() SQL 相同。也许我需要更多地关注嵌入通配符?
  • 澄清一下,您是否将"<key>NID</key><value>%m%</value>" 传递给SqlMethods.Like 并且仍然得到与没有% 通配符时相同的结果?
  • @Ahmad 实际上,没有。当我将您提到的字符串传递给 SqlMethods.Like() 方法时,SQL 输出是这样的: WHERE ([t0].[FormattedMessage] LIKE @p0 ESCAPE '~') ...interesting...
  • 您了解您的具体情况吗?

标签: c# linq-to-sql lambda wildcard


【解决方案1】:

String.Contains 在 LINQ to SQL 中实际上是作为LIKE 表达式实现的,因此这些查询是等价的:

query = query.Where(Log => Log.FormattedMessage.Contains("m"));
query = query.Where(Log => SqlMethods.Like(Log.FormattedMessage, "%m%"));

但是,使用SqlMethods.Like,您可以指定更复杂的模式,例如"%m%a%"。对我来说很好。从 Visual Studio 内部看不出真正的区别,因为要匹配的表达式放在 T-SQL 的参数中。

如果您要在分析器中记录 SQL 查询,它看起来像这样:

exec sp_executesql N'SELECT [t0].[ID], [t0].[FormattedMessage]
FROM [dbo].[Log] AS [t0]
WHERE [t0].[FormattedMessage] LIKE @p0',N'@p0 nvarchar(5)',@p0=N'%m%a%'

与问题本身无关,但 String.StartsWithString.EndsWidth 也转换为 SQL LIKE,当然模式略有不同。

【讨论】:

  • 感谢您的意见。我开始认为我的问题在于过滤器本身。如果您查看我的问题的底部,我会给出我正在查询的字符串。第一个返回记录。第二个,没有。如果有帮助,我将查询包含类似于我的过滤器示例的 xml 的 SQL 列。
  • @mcass20:这很奇怪。如果第一个过滤器返回一条记录,那么第二个过滤器肯定应该返回至少一个。如果你有 SQL Profiler,它可能有助于弄清楚发生了什么。
  • 如果您没有 SQL Profiler,当然也可以将 Console.Out(或其他 TextWriter)附加到 context.Log
  • SQL 输出看起来应该是这样,我已将其缩小到字符串本身。 "%m%" 返回记录,但 "NID%m%" 不返回。正如你所建议的,我也尝试了“%NID%m%%”......没有运气。
【解决方案2】:

通配符例如 m*,所以任何带有 m 的东西,对于通配符,你可以询问它是否 .Contains(m);它会得到任何包含“m”的东西。

如果您需要该表中所有结果的通配符,只需使用

query.ToList(); 

您现在拥有完整的日志列表。

希望对您有所帮助。

【讨论】:

  • 如果您需要获取多个字符串,您可以使用 ForEach 语句,检查每个字符串并将其与每个字符串一起添加到本地列表中。 “列表 规则 = 新列表(); var Logs = 新列表(); Rules.ForEach(rule => Logs.Add(query.Contains(rule)));”我相信这应该行得通!
猜你喜欢
  • 1970-01-01
  • 2013-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多