Reputation: 16970
In SQL Server, it is relatively straight forward to create a case-insensitive, accent-insensitive, LIKE
query using EF Core 5 and PredicateBuilder.
For example:
helene
should match Mme. Hélène Laurendeau
. It is important we can match a substring and not just a prefix or suffix.Assuming we have an entity Customer
with property Name
, the following snippet will work as expected:
var predicate = PredicateBuilder
.New<Customer>(c => EF.Functions.Collate(c.Name,
"Latin1_general_CI_AI")
.Contains("helen"));
var customers = context.Customers.AsExpandable().Where(predicate);
How we can we perform the same query in PostgreSQL (10 or higher)?
We just did a quick (basically 1:1) migration from SQL Server and are trying to update our code to make sure the general migration is possible. This question does not take possible query speed issues into account (see links for more info there.)
Upvotes: 0
Views: 2316
Reputation: 16970
Assuming your newly-created Postgres database is UTF8 (which I believe it is by default)
unaccent
is installed. If not, CREATE EXTENSION unaccent;
predicate
as follows:var predicate = PredicateBuilder
.New<Customer>(c => EF.Functions.ILike(EF.Functions.Unaccent(c.Name),
"%helen%"));
Notes: It is possible to collate answers from various questions on SO and other sources to reach this conclusion, but I've been unable to find one place where it makes sense post a comment with this solution that could be easily located. Also, I don't believe that introducing full-text search is the answer to this question, but happy to update it if I'm mistaken.
This answer is by far the best and most complete one I've seen and highly encourage people to dig into it when they have time. If you are trying to move from SQL Server over to Postgres as a prototype, though, this answer should save you a lot of pain and time :)
Some answers have suggested creating an index on a lowercase
/ unaccent
-ed version of the column but that does not directly work since unaccent
is not IMMUTABLE
. You can wrap these as required and then index them (examples in links.)
Also, attempting to pass a collation directly via EF.Functions
(after having created it on the server) does not appear to work either, but perhaps I am something missing about Postgres there.
It may be possible to tweak individual column collations.
Some relevant questions include:
Other sources:
Upvotes: 2