我使用的是 EF Core 3.1 + MySQL,使用此方法进行查询:
IQueryable<ApplicationUser> customers = from u in _context.Users where (u.Customer != null && u.IsActive) select u;
if (!String.IsNullOrEmpty(searchString))
{
customers = customers.Where(s => s.Email.Contains(searchString));
}
我升级到使用 EF.Function.Like 以获得更好的性能:
if (!String.IsNullOrEmpty(searchString))
{
customers = customers.Where(x => EF.Functions.Like(x.Email, $"%{searchString}%"));
}
但是是区分大小写的,如何使其不区分大小写?
来自文档:
注意,如果这个函数被翻译成SQL,那么比较的语义将取决于数据库配置。特别是,它可以区分大小写或不区分大小写。如果在客户端上评估此函数,那么它将始终使用不区分大小写的比较。
所以,这取决于您的服务器。
作为解决方法,您可以将参数设为大写。
if (!String.IsNullOrEmpty(searchString))
{
customers = customers.Where(x => EF.Functions.Like(x.Email.ToUpper(), $"%{searchString.ToUpper()}%"));
}
根据 this 应该有一个映射到
UPPER
的函数,这样你就可以获得正确的 SQL。
根据文档:
注意,如果这个函数被翻译成SQL,那么比较的语义将取决于数据库配置。特别是,它可以区分大小写或不区分大小写。如果在客户端上评估此函数,那么它将始终使用不区分大小写的比较。
因此,区分大小写的不是函数,而是您的数据库/列排序规则设置。您可以使用 Collate 函数指定不同的、不区分大小写的排序规则。更多关于 MySQL 排序规则。
对于 postgres 使用
EF.Functions.ILike
:
customers = customers.Where(x => EF.Functions.ILike(x.Email, $"%{searchString}%"));
这将被翻译成这个查询:
SELECT c."Email"
FROM yourSchema."Customers" AS c
WHERE c."Email" ILIKE @__Format_1 ESCAPE ''
而 toLower (或 toUpper)被显式调用:
SELECT c."Email"
FROM yourSchema."Customers" AS c
WHERE lower(c."Email") LIKE @__ToLower_0_rewritten ESCAPE '\'
这里是 npgsql 的文档,供进一步阅读。