12

I am building up a query in C#. For integer and string fields, case is quite simple. For date fields, I am using following query:

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

How I can perform following SQL LIKE query in LINQ?

select * from table where myTextColumn LIKE '%abc%';
Behzad Qureshi
  • 546
  • 1
  • 7
  • 16

5 Answers5

39

There are lots of possibilities for Like in Linq:

For LIKE '%abc%';

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

For LIKE 'abc%';

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

For LIKE '%abc';

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

Updates : If you need to add Date comparison as well means you can do like the following:

DateTime date2Compare = new DateTime(2017, 1, 20);
list.Where(x => myDateColumn >= date2Compare && x.myTextColumn.Contains('abc'));
sujith karivelil
  • 28,671
  • 6
  • 55
  • 88
7

Placement of the Wildcard '%' in a LIKE clause makes a difference, and C# has the methods to back this up. Below is what the placements of the Wildcard means.

LIKE '%abc'

Meaning: Find any word ending with 'abc'.

C# equivalent: EndsWith

LIKE 'abc%'

Meaning: Find any word starting with 'abc', and you don't care about the text after.

C# equivalent: StartWith

LIKE '%abc%'

Meaning: Find any word that contains 'abc', and you don't care where in the word it appears.

C# equivalent: Contains

monstertjie_za
  • 7,277
  • 8
  • 42
  • 73
4

You can use Contains with myTextColumn field

var date = new DateTime(2017,1,20);
list.Where(x => x.myDateColumn >= date  && x.myTextColumn.Contains('abc'));
Satpal
  • 132,252
  • 13
  • 159
  • 168
2

Let's try solving the problem in general case. Suppose we're given something like

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

we can try convert like expression into corresponding regular one:

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("%", ".*") + "$"; 
}

usage:

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

you may want to convert the data into string before matching:

 var result list
  .Where(x => Regex.IsMatch(x.myDate.ToString(), LikeToRegular("%abc%")));
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
2

While other answers (including the accepted one) are 80% correct, there are some caveats.

T-SQL allows the Like statement to have wildcards not just at the start and end of a string, but also in the middle. And % is not the only special char in the syntax, see docs for details.

.NET Core has EF.Functions.Like() method that is literally translated into LIKE statement. See the below example.

//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"));

Caveats:

  • This only works with a server-side evaluation. An attempt to use this feature in client-side evaluation will throw NotSupportedException.
  • There is a noticeable difference in SQL translation between EF.Functions.Like and Contains or StartsWith, which may impact performance.

If you are certain you are using server-side evaluation and performance is important, use EF.Functions.Like.

KifoPL
  • 981
  • 7
  • 18