You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL与EF Core 8土耳其字符不区分大小写搜索问题求解

在PostgreSQL 15 + EF Core 8中解决土耳其字符的不区分大小写搜索问题

问题根源

PostgreSQL的大小写转换、字符串比较逻辑依赖排序规则,默认规则未适配土耳其语的特殊大小写映射(I→ı、i→İ);EF Core默认字符串操作也未自动适配土耳其语规则,导致搜索结果不符合预期。

解决方案

1. 为数据库/列配置土耳其语排序规则

这是基础前提,确保PostgreSQL处理土耳其字符时使用正确的大小写转换逻辑。

新建表时指定排序规则

CREATE TABLE Products (
    ID INT PRIMARY KEY,
    Name VARCHAR(255) COLLATE "tr_TR.utf8"
);

修改现有列的排序规则

ALTER TABLE Products ALTER COLUMN Name TYPE VARCHAR(255) COLLATE "tr_TR.utf8";

2. EF Core查询适配方案

方案一:使用EF.Functions.Collate强制指定排序规则

在查询中显式指定土耳其语排序规则,让Contains操作按土耳其语逻辑执行:

var searchTerm = "milk"; // 支持"mılk"、"MILK"、"MİLK"任意形式
var result = Products
    .Where(p => EF.Functions.Collate(p.Name, "tr_TR.utf8")
                   .Contains(EF.Functions.Collate(searchTerm, "tr_TR.utf8")))
    .ToList();

方案二:自定义PostgreSQL函数+EF Core映射

如果需要更复用的逻辑,可以创建自定义函数:

  1. 在PostgreSQL中创建函数:
CREATE OR REPLACE FUNCTION turkish_contains(column_text text, search_text text)
RETURNS boolean AS $$
BEGIN
    RETURN LOWER($1 COLLATE "tr_TR.utf8") LIKE '%' || LOWER($2 COLLATE "tr_TR.utf8") || '%';
END;
$$ LANGUAGE plpgsql IMMUTABLE;
  1. 在EF Core的DbContext中映射该函数:
[DbFunction("turkish_contains")]
public static bool TurkishContains(string column, string searchTerm)
    => throw new NotImplementedException("该函数已映射到PostgreSQL");
  1. 查询时直接调用:
var result = Products
    .Where(p => TurkishContains(p.Name, "milk"))
    .ToList();

3. 修复citext无效问题

默认citext未使用土耳其语排序规则,需创建自定义citext类型:

CREATE COLLATION "tr_TR.utf8" (LOCALE = 'tr_TR.utf8');
CREATE TYPE tr_citext AS citext COLLATE "tr_TR.utf8";

之后将列类型改为tr_citext,即可实现土耳其语大小写不敏感的字符串存储与比较。

验证用户测试案例

当列FullName配置tr_TR.utf8排序规则后,以下查询将正常返回结果:

SELECT p."FullName" 
FROM "Personnel" p 
WHERE LOWER(p."FullName") = LOWER('Elif dirik');

此时LOWER会按照土耳其语规则转换:Elif→elif,ELİF→elif,两者匹配。

内容的提问来源于stack exchange,提问作者Elif Sena

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 15:55:05