问题描述
通过忽略重音和大小写的 Where
方法使用 LINQ 过滤元素的最简单方法是什么?
到目前为止,我已经能够通过在属性上调用方法来忽略大小写,我认为这不是一个好主意,因为它为每个元素调用相同的方法(对吗?).
这是我目前得到的:
var result = from p in People其中 p.Name.ToUpper().Contains(filter.ToUpper())选择 p;
请告诉我这是否是一个好习惯,以及忽略重音的最简单方法.
要忽略大小写和重音(变音符号),您可以首先定义一个扩展方法,如下所示:
public static string RemoveDiacritics(this String s){String normalizedString = s.Normalize(NormalizationForm.FormD);StringBuilder stringBuilder = new StringBuilder();for (int i = 0; i < normalizedString.Length; i++){字符 c = normalizedString[i];if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)stringBuilder.Append(c);}返回 stringBuilder.ToString();}
(修改自 忽略字符串比较中的重音字母)
现在您可以运行您的查询:
string queryText = filter.ToUpper().RemoveDiacritics();var result = from p in People其中 p.Name.ToUpper().RemoveDiacritics() == queryText选择 p;
如果您只是在 C# 中迭代一个集合,这很好,但是如果您使用 LINQ to SQL,最好避免在 LINQ 查询中使用非标准方法(包括扩展方法).这是因为您的代码无法转换为有效的 SQL,因此无法在具有所有可爱性能优化的 SQL Server 上运行.
由于在 LINQ to SQL 中似乎没有忽略重音的标准方法,在这种情况下,我建议将您要搜索的字段类型更改为不区分大小写和重音 (CI_AI).
以你的例子:
ALTER TABLE People ALTER COLUMN Name [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AI
您的查询现在应该忽略重音和大小写.
请注意,在运行上述查询之前,您需要暂时删除字段上的任何唯一约束,例如
ALTER TABLE People DROP CONSTRAINT UQ_People_Name
现在您的 LINQ 查询将是:
var result = from p in People其中 p.Name == 过滤器选择 p;
在此处查看相关问题.>
What is the easiest way to filter elements with LINQ through the Where
method ignoring accentuation and case?
So far, I've been able to ignore Casing by calling methods on the properties, which I dont think is a good idea because it calls the same method for every element (right?).
So here's what I got so far:
var result = from p in People
where p.Name.ToUpper().Contains(filter.ToUpper())
select p;
Please tell me if this is a good practice, and the easiest way to ignore accentuation.
To ignore case and accents (diacritics) you can first define an extension method like this:
public static string RemoveDiacritics(this String s)
{
String normalizedString = s.Normalize(NormalizationForm.FormD);
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < normalizedString.Length; i++)
{
Char c = normalizedString[i];
if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
stringBuilder.Append(c);
}
return stringBuilder.ToString();
}
(Modified from Ignoring accented letters in string comparison)
Now you can run your query:
string queryText = filter.ToUpper().RemoveDiacritics();
var result = from p in People
where p.Name.ToUpper().RemoveDiacritics() == queryText
select p;
This is fine if you are just iterating over a collection in C#, but if you are using LINQ to SQL it is preferable to avoid non-standard methods (including extension methods) in your LINQ query. This is because your code cannot be converted into valid SQL and hence run on SQL Server with all its lovely performance optimization.
Since there doesn't seem to be a standard way of ignoring accents within LINQ to SQL, in this case I would suggest changing the field type that you want to search to be case- and accent-insensitive (CI_AI).
With your example:
ALTER TABLE People ALTER COLUMN Name [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AI
Your query should now ignore accentuation and case.
Note that you will need to temporarily remove any unique constraints on the field before running the above query, e.g.
ALTER TABLE People DROP CONSTRAINT UQ_People_Name
Now your LINQ query would simply be:
var result = from p in People
where p.Name == filter
select p;
See related question here.
这篇关于忽略重音和大小写的 LINQ的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!