在C# LINQ中使用SQL LIKE操作符

12

我正在使用C#构建查询。对于整数和字符串字段,情况非常简单。对于日期字段,我使用以下查询:

list.Where("myDateColumn >= DateTime(2017,1,20)");

我该如何在LINQ中执行以下SQL LIKE查询?

select * from table where myTextColumn LIKE '%abc%';

1
使用 .Contains - monstertjie_za
@monstertjie_za:我想在同一日期筛选器中添加类似的过滤器。 - Behzad Qureshi
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - monstertjie_za
那么,我不能在字符串中指定类似查询的方式吗? - Behzad Qureshi
不,C# 不是 SQL。就像 @un-lucky 提到的那样,如果你只想查找以指定文本开头的单词,可以使用 StartWith;如果你只想查找以指定文本结尾的单词,可以使用 EndsWith;如果你想查找包含指定文本的任何位置的单词,则可以使用 Contains。你知道 SQL LIKE 子句中通配符 '%' 的作用吗?通配符的位置很重要,而 C# 有相应的方法来支持这一点。 - monstertjie_za
显示剩余5条评论
5个回答

39

在 Linq 中,Like 操作有很多可能性:

对于 LIKE '%abc%';

list.Where(x => x.myTextColumn.Contains('abc'));

对于 LIKE 'abc%';

list.Where(x => x.myTextColumn.StartWith('abc'));
对于 LIKE '%abc';
list.Where(x => x.myTextColumn.EndsWith('abc'));

更新:如果您需要添加日期比较,则可以按照以下方式进行操作:

DateTime date2Compare = new DateTime(2017, 1, 20);
list.Where(x => myDateColumn >= date2Compare && x.myTextColumn.Contains('abc'));

我想在相同日期筛选器中添加类似的筛选器。 - Behzad Qureshi
请仔细阅读问题中的注释,您将了解实际问题的情况。 - Behzad Qureshi
@BehzadQureshi:请查看我的回答中的更新内容:如果我误解了您指定的场景,请原谅我。 - sujith karivelil
缺失:那么我无法在字符串中指定类似的查询吗? - Behzad Qureshi
请尝试一下我建议的内容,并让我知道输出结果与您预期的输出结果有何不同。 - sujith karivelil
显示剩余2条评论

7
在LIKE子句中通配符'%'的位置很重要,而C#有相应的方法来支持它。下面是通配符位置的含义。
LIKE '%abc' 意思:查找以'abc'结尾的任何单词。 C#等效:EndsWith
LIKE 'abc%' 意思:查找以'abc'开头的任何单词,并且您不关心后面的文本。 C#等效:StartWith
LIKE '%abc%' 意思:查找包含'abc'的任何单词,并且您不关心它出现在单词中的位置。 C#等效:Contains

4

您可以使用Contains函数与myTextColumn字段一起使用。

var date = new DateTime(2017,1,20);
list.Where(x => x.myDateColumn >= date  && x.myTextColumn.Contains('abc'));

2
其他答案(包括被接受的答案)大约80%正确,但有一些注意事项。
T-SQL允许Like语句在字符串的中间使用通配符,而不仅仅是在开头和结尾。并且“%”不是语法中唯一的特殊字符,请参见docs以获取详细信息。
.NET Core具有EF.Functions.Like()方法,该方法直接转换为LIKE语句。请参见下面的示例。
//assuming there is a db context with a table of Foos
await using var dbContext = new SqlContext();

//assuming table of Foos has Ipsum, Iptum, Ipuum
var result = dbContext.Foos.Where(x
    => EF.Functions.Like(x.Bar, "Ip_um"));

注意事项:
  • 这仅适用于服务器端评估。尝试在客户端评估中使用此功能将引发NotSupportedException
  • EF.Functions.LikeContainsStartsWith之间的SQL翻译存在明显差异,这可能会影响性能

如果您确定正在使用服务器端评估并且性能很重要,请使用EF.Functions.Like


2

让我们尝试在一般情况下解决问题。假设我们得到的是这样的东西:

select ...
 where ... MyField like '%abc%'

我们可以尝试将“like”表达式转换为相应的“regular”表达式:
Like | Description                       |Regular
-------------------------------------------------
   _ | any character  (one and only one) | .
   % | any characters (zero or more)     | .*

Implementation

// If you want to implement both "*" and "?"
private static String LikeToRegular(String value) {
  return "^" + Regex.Escape(value).Replace("_", ".").Replace("%", ".*") + "$"; 
}

使用方法:

var result list
  .Where(x => Regex.IsMatch(x.myTextColumn, LikeToRegular("%abc%")));

在匹配之前,您可能需要将数据转换为字符串

 var result list
  .Where(x => Regex.IsMatch(x.myDate.ToString(), LikeToRegular("%abc%")));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接