Skip to content

Conversation

@guardrex
Copy link
Collaborator

@guardrex guardrex commented Jul 29, 2025

Fixes #35851

Thanks @rodbeck! 🚀

Dan, we might not want to do this, or we might want to do something different. I started by trying to update the instructions to specifically tell SQLite folks to use case sensitive search terms (e.g., "Road Warrior" instead of "road warrior"). The problem with modifying all of the instructions that way is that it muddies up the text with distracting parenthetical information that still doesn't match the images. Therefore if we do anything, it might be best to show the workaround approach of using ToLower (on this PR), which is simpler and quicker than getting into the weeds with SQLite dB collation, which we do cross-link.


Internal previews

📄 File 🔗 Preview link
aspnetcore/blazor/tutorials/movie-database-app/part-6.md aspnetcore/blazor/tutorials/movie-database-app/part-6

@guardrex guardrex requested review from Copilot and danroth27 July 29, 2025 11:50
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds SQLite-specific guidance to handle case-sensitive filtering issues in the Blazor movie database tutorial. The changes provide a workaround using ToLower() to ensure case-insensitive filtering works consistently across different database collations.

  • Adds NOTE sections explaining SQLite case sensitivity issues with filtering
  • Provides ToLower() workaround examples for case-sensitive database collations
  • Includes additional resources section with links to relevant GitHub issues and EF Core documentation

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
aspnetcore/blazor/tutorials/movie-database-app/part-6.md Updates existing content explanation and adds SQLite workaround inline with the filtering discussion
aspnetcore/blazor/tutorials/movie-database-app/part-8.md Adds NOTE section with SQLite workaround and new Additional resources section with reference links

@danroth27
Copy link
Member

@AndriySvyryd @luisquintanilla @roji What do you recommend here in this intro tutorial for dealing with SQLite case sensitivity? Should we be configuring a collation on the model instead?

@guardrex guardrex self-assigned this Jul 29, 2025
@roji
Copy link
Member

roji commented Jul 29, 2025

Yeah, the right solution here is to create your column with the NOCASE collation (SQLite documentation on collations, EF documentation on collations) - that's what we should be guiding users towards.

Now, I'm not aware of any support for a "database" collation in SQLite; this does exist in other databases, but AFAIK not in SQLite. SQLite allows you to define collations on the column level - that's the thing to show (so basically this) with NOCASE).

Other than that, FYI the "workaround" with using ToLower() is generally discouraged as it means any index on the column won't be used. We generally try to not show that anti-pattern as people invariably copy-paste it as the simple/easy/intuitive thing, and frequently don't realize they're killing perf by doing it. So I'd recommend against showing this.

BTW: this PR is referencing System.Data.Objects.DataClasses.EntityCollection, which is the old non-core EF6. I'm assuming you want to show EF Core, no?

/cc @cincuranet

@danroth27
Copy link
Member

the right solution here is to create your column with the NOCASE collation

@roji We can't assume the user is using SQLite - if the user is on Windows in VS, I believe they'll get SQL Server by default. I assume the NOCASE collation is SQLite specific, so we'll need to add some text to tell the user to add that only if they're using SQLite, correct?

@cincuranet
Copy link
Contributor

Yes. NOCASE is SQLite specific. And only ASCII characters are case folded.

A cross-database "workaround" could be to have dedicated extra column for search and this column will be lower-cased before SaveChanges is called.

@roji
Copy link
Member

roji commented Jul 29, 2025

Sorry @danroth27, misread this as being specific to SQLite. Unfortunately the situation with collations really is different across databases - SQL Server is already case-insensitive by default (unless the user specifically tweaked the SQL Server installation, they get case-insensitive behavior), where PostgreSQL and SQLite are case-sensitive. Actual collation names are database-specific.

So I'd basically tell users to configure their column collation if they're not getting the results they want, and point them to the EF page above.

@guardrex
Copy link
Collaborator Author

Thanks folks! ... I have enough info to fix the tutorial now.

@danroth27 ... It will be tomorrow morning, and I'll ping you back here when this is ready for an 👁️.

@guardrex
Copy link
Collaborator Author

@danroth27 ... Updates complete. Ready for a look. 👀

@guardrex guardrex changed the title SQLite workaround for case insensitive filtering SQLite guidance for case insensitive filtering Jul 30, 2025
Copy link
Member

@danroth27 danroth27 left a comment

Choose a reason for hiding this comment

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

One minor suggestion to try to future proof the content a bit in case we ever decide to change the default database provider we use.

@guardrex
Copy link
Collaborator Author

guardrex commented Jul 30, 2025

That lick'd IT. It now reads ...

To adopt case-insensitive collation when using SQLite (UseSqlite is called in Program.cs), open the Data/BlazorWebAppMoviesContext.cs file. Inside the BlazorWebAppMoviesContext class, add the following code:

Thanks everyone! 🍻

@guardrex guardrex merged commit e8c64e6 into main Jul 30, 2025
3 checks passed
@guardrex guardrex deleted the guardrex/blazor-movie-db-tutorial branch July 30, 2025 19:30
Comment on lines +65 to +70
```csharp
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.UseCollation("SQL_Latin1_General_CP1_CS_AS");
}
```
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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Case sensitive comparison

6 participants