【发布时间】:2020-11-24 09:30:55
【问题描述】:
我有一个简单的字符串扩展方法:
public static class FrenchStringExtensions
{
public static string ReplaceAccents(this string str)
{
return str
.Replace("ç", "c")
.Replace("é", "e")
.Replace("ê", "e")
.Replace("è", "e")
.Replace("ë", "e")
.Replace("â", "a")
.Replace("à", "a")
.Replace("î", "i")
.Replace("ï", "i")
.Replace("ô", "o")
.Replace("û", "u")
.Replace("ù", "u")
.Replace("ü", "u");
}
}
当我尝试像这样在Where() 子句中调用此方法时:
var supportTeamsQuery = this.MasterContext.IncidentSupportTeams
.AsNoTracking()
.IsActive();
if (!string.IsNullOrEmpty(pattern))
{
pattern = pattern.ToLower().ReplaceAccents().Trim();
supportTeamsQuery = supportTeamsQuery
.Where(st =>
st.Name.ToLower().ReplaceAccents().Contains(pattern)
);
}
我有一个错误:无法翻译 LINQ 表达式...
如果我在Where() 内使用Replace() 调用,它工作正常。例如:
supportTeamsQuery = supportTeamsQuery
.Where(st =>
st.Name
.ToLower()
.Replace("ç", "c")
.Replace("é", "e")
.Replace("ê", "e")
...
.Contains(pattern)
);
但我的代码中有几个地方需要以这种方式转换字符串,因此我想将其移至单独的方法。
有可能让它工作吗?
【问题讨论】:
-
IMO,与其这样查询数据(查询将无效),不如存储规范化名称。也就是说,您应该在 在数据库中存储名称之前调用 ReplaceAccents。只需存储“带重音的名称”和“标准化名称”。第一个用于向用户显示数据,第二个用于搜索。
-
发生此错误是因为您的 LINQ 将被转换为 SqlServer Query 并且它不能(没有内置版本
ReplaceAccent在 SQL Server 中)。如果你的数据在内存中,你的函数就可以正常工作。 -
我认为您可以反之亦然,将您的
pattern字符串更改为重音类型。这样你的查询就可以工作了。 -
您正在尝试做的似乎是重新发明排序规则重音敏感性。只需将数据库的排序规则更改为不区分重音 (AI),或者如果您只需要某个查询,则需要使用 EF Core 5,请参阅docs.microsoft.com/en-us/ef/core/miscellaneous/…
-
您还可以通过使用不区分大小写 (CI) 排序规则而不是区分大小写 (CS) 来摆脱 ToLower