SQL
Linq
Programming
C#
.NET

How to do SQL Like in Linq?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

LINQ does not have a direct LIKE keyword, but the same idea can be expressed with string methods or with provider-specific SQL translation helpers. The right approach depends on where the query runs. LINQ-to-Objects uses normal .NET string behavior, while Entity Framework or another ORM may translate the expression into SQL.

Map Simple LIKE Patterns to String Methods

Many SQL LIKE patterns correspond directly to common string operations.

  • ''%term%' maps to Contains'
  • ''term%' maps to StartsWith'
  • ''%term' maps to EndsWith'

Example with Entity Framework:

csharp
1var contains = db.Employees
2    .Where(e => e.Name.Contains("John"))
3    .ToList();
4
5var starts = db.Employees
6    .Where(e => e.Name.StartsWith("Jo"))
7    .ToList();
8
9var ends = db.Employees
10    .Where(e => e.Name.EndsWith("son"))
11    .ToList();

These methods are often enough when the search pattern is simple and predictable.

Use EF.Functions.Like for Explicit SQL Patterns

If you are using EF Core and need actual wildcard patterns, EF.Functions.Like is the clearest option.

csharp
1using Microsoft.EntityFrameworkCore;
2
3var users = db.Users
4    .Where(u => EF.Functions.Like(u.Email, "%@example.com"))
5    .ToList();

This is especially useful when the pattern is built dynamically or uses SQL wildcards such as _ for a single character.

csharp
var codes = db.Codes
    .Where(c => EF.Functions.Like(c.Value, "A_1"))
    .ToList();

That communicates SQL intent more directly than trying to compose several string methods.

Understand the Difference Between In-Memory and Database Queries

With LINQ-to-Objects, methods such as Contains and StartsWith run as normal .NET string operations in memory.

csharp
var names = new List<string> { "Alice", "Alicia", "Bob" };
var local = names.Where(n => n.Contains("Ali")).ToList();

With Entity Framework, the same expression is translated to SQL when possible. That means behavior can depend on the database provider, collation, and what the provider knows how to translate.

This distinction matters because code that works in memory does not always behave identically once SQL translation is involved.

Case Sensitivity Depends on Collation

Many developers expect C# method names to decide case behavior, but database collation often matters more. A query can behave differently on SQL Server, PostgreSQL, or SQLite depending on the configured collation rules.

If you need deterministic case behavior, design for it explicitly rather than assuming the default will match your expectations. In some cases that means normalizing data, and in others it means choosing the right database collation or provider-specific feature.

Escape User Input When Building Patterns

If users can type % or _, those characters may act as wildcards in a LIKE pattern. Escape or sanitize the input before embedding it into a pattern string.

csharp
1string EscapeLike(string input) =>
2    input.Replace("[", "[[]")
3         .Replace("%", "[%]")
4         .Replace("_", "[_]");
5
6var term = EscapeLike(userInput);
7
8var products = db.Products
9    .Where(p => EF.Functions.Like(p.Name, $"%{term}%"))
10    .ToList();

This is partly a correctness issue and partly a predictability issue. Users searching for a literal percent sign should not accidentally trigger a wildcard search.

Inspect Translation and Think About Performance

A leading wildcard such as '%term' or '%term%' is often less index-friendly than a prefix search such as 'term%'. If performance matters, check the generated SQL and measure the query plan rather than assuming all pattern searches cost the same.

csharp
1var sql = db.Employees
2    .Where(e => EF.Functions.Like(e.Name, "%abc%"))
3    .ToQueryString();
4
5Console.WriteLine(sql);

Seeing the generated SQL is often the fastest way to confirm that your LINQ expression translated the way you expected.

Common Pitfalls

The biggest pitfall is assuming every LINQ provider translates string methods in exactly the same way. Provider behavior can differ.

Another issue is ignoring collation and then being surprised by case-sensitive or case-insensitive matches that differ across environments.

People also often build wildcard patterns from raw user input without escaping % or _, which changes query semantics.

Finally, %term% searches are convenient but can be expensive on large indexed tables. Measure before depending on them heavily.

Summary

  • Use Contains, StartsWith, and EndsWith for simple LIKE-style searches.
  • Use EF.Functions.Like when you want explicit SQL wildcard patterns in EF Core.
  • Remember that LINQ-to-Objects and database-backed LINQ do not behave identically.
  • Treat collation and case sensitivity as database concerns, not just C# concerns.
  • Escape wildcard characters in user input and inspect generated SQL when performance matters.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.