我有一个数据库表,其中包含带有重音字符的名称。喜欢ä
等等。
我需要使用 EF4 从包含一些子字符串的表中获取所有记录,而不管重音如何。
所以下面的代码:
myEntities.Items.Where(i => i.Name.Contains("a"));
应该返回名称包含 的a
所有项目,以及包含 的所有项目ä
,â
依此类推。这可能吗?
我有一个数据库表,其中包含带有重音字符的名称。喜欢ä
等等。
我需要使用 EF4 从包含一些子字符串的表中获取所有记录,而不管重音如何。
所以下面的代码:
myEntities.Items.Where(i => i.Name.Contains("a"));
应该返回名称包含 的a
所有项目,以及包含 的所有项目ä
,â
依此类推。这可能吗?
如果您在 Name 列上设置了不区分重音的排序规则,则查询应按要求工作。
设置不区分重音的排序规则将解决问题。
您可以使用下一个查询更改 SQL Server 和 Azure 数据库中列的排序规则。
ALTER TABLE TableName
ALTER COLUMN ColumnName NVARCHAR (100)
COLLATE SQL_LATIN1_GENERAL_CP1_CI_AI NOT NULL
SQL_LATIN1_GENERAL_CP1_CI_AI
LATIN1_GENERAL
是英语(美国)的排序规则,CP1
是代码页 1252,CI
不区分大小写 且不区分AI
重音。
我知道这不是那么干净的解决方案,但在阅读完这篇文章后,我尝试了这样的事情:
var query = this.DataContext.Users.SqlQuery(string.Format("SELECT * FROM dbo.Users WHERE LastName like '%{0}%' COLLATE Latin1_general_CI_AI", parameters.SearchTerm));
之后,您仍然可以在“查询”对象上调用方法,例如 Count、OrderBy、Skip 等。
通过将排序规则 SQL_Latin1_General_CP1253_CI_AI 应用于输入字符串,您可以创建一个 SQL 函数来删除变音符号,如下所示:
CREATE FUNCTION [dbo].[RemoveDiacritics] (
@input varchar(max)
) RETURNS varchar(max)
AS BEGIN
DECLARE @result VARCHAR(max);
select @result = @input collate SQL_Latin1_General_CP1253_CI_AI
return @result
END
然后通过将其映射到属性 DbFunction 将其添加到 DB 上下文(在本例中为 ApplicationDbContext):
public class ApplicationDbContext : IdentityDbContext<CustomIdentityUser>
{
[DbFunction("RemoveDiacritics", "dbo")]
public static string RemoveDiacritics(string input)
{
throw new NotImplementedException("This method can only be used with LINQ.");
}
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
并在 LINQ 查询中使用它,例如:
var query = await db.Users.Where(a => ApplicationDbContext.RemoveDiacritics(a.Name).Contains(ApplicationDbContext.RemoveDiacritics(filter))).tolListAsync();
Stuart Dunkeld 建议的不区分重音的排序规则绝对是最好的解决方案......
但也许很高兴知道:
Michael Kaplan 曾经发布过关于剥离变音符号的帖子:
static string RemoveDiacritics(string stIn)
{
string stFormD = stIn.Normalize(NormalizationForm.FormD);
StringBuilder sb = new StringBuilder();
for(int ich = 0; ich < stFormD.Length; ich++)
{
UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);
if(uc != UnicodeCategory.NonSpacingMark)
{
sb.Append(stFormD[ich]);
}
}
return(sb.ToString().Normalize(NormalizationForm.FormC));
}
所以你的代码是:
myEntities.Items.Where(i => RemoveDiacritics(i.Name).Contains("a"));