Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions aspnetcore/blazor/tutorials/movie-database-app/part-6.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,16 @@ Change the `QuickGrid` component's <xref:Microsoft.AspNetCore.Components.QuickGr

The `movie => movie.Title!.Contains(...)` code is a *lambda expression*. Lambdas are used in method-based LINQ queries as arguments to standard query operator methods such as the <xref:System.Linq.Queryable.Where%2A> or <xref:System.String.Contains%2A> methods. LINQ queries aren't executed when they're defined or when they're modified by calling a method, such as <xref:System.Linq.Queryable.Where%2A>, <xref:System.String.Contains%2A>, or <xref:System.Linq.Queryable.OrderBy%2A>. Rather, query execution is deferred. The evaluation of an expression is delayed until its realized value is iterated.

The <xref:System.Data.Objects.DataClasses.EntityCollection%601.Contains%2A> method is run on the database, not in the C# code. The case sensitivity of the query depends on the database and the collation. For SQL Server, <xref:System.String.Contains%2A> maps to [SQL `LIKE`](/sql/t-sql/language-elements/like-transact-sql), which is case insensitive. SQLite with default collation provides a mixture of case sensitive and case insensitive filtering, depending on the query. For information on making case insensitive SQLite queries, see the [Additional resources](#additional-resources) section of this article.
The <xref:System.Data.Objects.DataClasses.EntityCollection%601.Contains%2A> method is run on the database, not in the C# code. The case sensitivity of the query depends on the database and the collation. For SQL Server, <xref:System.String.Contains%2A> maps to [SQL `LIKE`](/sql/t-sql/language-elements/like-transact-sql), which is case insensitive. SQLite with default collation provides a mixture of case-sensitive and case-insensitive filtering, depending on the query. The remainder of this tutorial assumes case-insensitive database collation.

To adopt case-insensitive collation when using SQLite (<xref:Microsoft.EntityFrameworkCore.SqliteDbContextOptionsBuilderExtensions.UseSqlite%2A> is called in `Program.cs`), open the `Data/BlazorWebAppMoviesContext.cs` file. Inside the `BlazorWebAppMoviesContext` class, add the following code:

```csharp
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.UseCollation("SQL_Latin1_General_CP1_CS_AS");
}
```
Comment on lines +65 to +70
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect on multiple levels. But crucially EF translates Contains to instr on SQLite and that always performs a case sensitive comparison independently of the collation. The correct solution is to call ToLower first.

Copy link
Collaborator Author

@guardrex guardrex Jul 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't reply here ... let's move the discussion to #35868.

I see. Where is this covered in EF Core docs because ...

https://learn.microsoft.com/en-us/ef/core/miscellaneous/collations-and-case-sensitivity

... isn't a good cross-link for this particular scenario, namely SQLite and case sensitivity.

Copy link
Collaborator Author

@guardrex guardrex Jul 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't reply here ... let's move the discussion to #35868.

BTW @AndriySvyryd ... It hasn't gone live, so you did catch it in time. Thanks for jumping on to let me know. I'll fix it right now.

Copy link
Collaborator Author

@guardrex guardrex Jul 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't reply here ... let's move the discussion to #35868.

I'm looking back over the earlier remarks, and there seems to be disagreement ...

SQLite allows you to define collations on the column level - that's the thing to show (so basically this) with NOCASE).

... versus ...

The correct solution is to call ToLower first.

So ... will the following work?

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Movie>().Property(c => c.Title).UseCollation("NOCASE");
}

If it's unclear, I'll test it, but I'll do so in the morning. I'm just about at 🛌💤🐑🐑🐑 time.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's take it up on the PR. I'll start with @roji, and then I have a feeling that we'll be moving to @AndriySvyryd over there.

#35868


Run the app and navigate to the movies `Index` page at `/movies`. The movies in the database load:

Expand Down Expand Up @@ -143,10 +152,7 @@ Stop the app by closing the browser's window and pressing <kbd>Ctrl</kbd>+<kbd>C
* [LINQ documentation](/dotnet/csharp/programming-guide/concepts/linq/)
* [Write C# LINQ queries to query data (C# documentation)](/dotnet/csharp/programming-guide/concepts/linq/query-syntax-and-method-syntax-in-linq)
* [Lambda Expression (C# documentation](/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions)
* Case insensitive SQLite queries
* [How to use case-insensitive query with Sqlite provider? (`dotnet/efcore` #11414)](https://github.com/dotnet/efcore/issues/11414)
* [How to make a SQLite column case insensitive (`dotnet/AspNetCore.Docs` #22314)](https://github.com/dotnet/AspNetCore.Docs/issues/22314)
* [Collations and Case Sensitivity](/ef/core/miscellaneous/collations-and-case-sensitivity)
* [Collations and Case Sensitivity](/ef/core/miscellaneous/collations-and-case-sensitivity)

## Legal

Expand Down