C# 动态LINQ不区分重音的字符串查询
我正在开发一个C#.Net MVC应用程序,并试图实现一种通用的实体字段搜索方法。随着我们的页面不断增长,我不想在每次添加新页面时编写搜索方法 为此,我正在使用Dynamic.Core LINQ查询:请访问: 我实现它的方式如下:在视图中的用户输入时,应用程序向控制器发送一个ajax请求,告诉它搜索该特定值,然后显示上一个值所在的新列表 问题是:我可以使它不区分大小写,但不区分重音,我想知道是否有人可以帮助我做到这一点 这是我的密码:C# 动态LINQ不区分重音的字符串查询,c#,asp.net-mvc,entity-framework,ef-code-first,linq-to-entities,C#,Asp.net Mvc,Entity Framework,Ef Code First,Linq To Entities,我正在开发一个C#.Net MVC应用程序,并试图实现一种通用的实体字段搜索方法。随着我们的页面不断增长,我不想在每次添加新页面时编写搜索方法 为此,我正在使用Dynamic.Core LINQ查询:请访问: 我实现它的方式如下:在视图中的用户输入时,应用程序向控制器发送一个ajax请求,告诉它搜索该特定值,然后显示上一个值所在的新列表 问题是:我可以使它不区分大小写,但不区分重音,我想知道是否有人可以帮助我做到这一点 这是我的密码: public static List<T> Se
public static List<T> SearchEntityList<T>(this IQueryable<T> entityList, string searchBy, List<string> fieldsToCheck)
{
if (searchBy == null)
return entityList.ToList();
searchBy = searchBy.ToLower().RemoveDiacriticsUtil();
// Dynamic LINQ Library
string query = "";
foreach (string str in fieldsToCheck)
{
query += str + ".ToString().ToLower().Contains(@0) ||";
}
if (query != null)
{
// Removes the last "OR" inserted on the foreach here on top
query = query.Substring(0,query.Length - 3);
try
{
entityList = entityList.Where(query, searchBy);
}
catch (Exception e)
{
// query is wrong, list wont be filtered.
return entityList.ToList();
}
}
List<T> filteredList = entityList.ToList(); ;
return filteredList;
}
用这个
query += str + "Collate(" + str + ".toString(), \"SQL_Latin1_General_CP1_CI_AI\").Contains(@0) ||";
现在我不能让它工作。
出现以下错误:
"No applicable method 'Collate' exists in type '...'"
我测试了很多其他东西,比如RemoveDiacritics等等。。但它们不能处理动态字符串linq查询
我想知道是否有人已经有同样的问题。谢谢 你在正确的轨道上。
在我们使用动态linq之前,您需要注册自定义扩展方法:
// Registration for the default custom type handler
[DynamicLinqType]
public static class MyExtensions
{
// taken from: https://stackoverflow.com/questions/359827/ignoring-accented-letters-in-string-comparison/368850
public static string RemoveDiacritics(this string text)
{
return string.Concat(
text.Normalize(NormalizationForm.FormD)
.Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) !=
UnicodeCategory.NonSpacingMark)
).Normalize(NormalizationForm.FormC);
}
}
public static class Entry
{
public static void Main(string[] args)
{
// your input
var query = "éè";
// clean it using your extension method
var cleanQuery = query.RemoveDiacritics();
// a test set for this demo
IQueryable<string> testSet = new EnumerableQuery<string>(new List<string>()
{
"soméè", "tèèst", "séét", "BBeeBB", "NoMatchHere"
});
var results = testSet.Where("it.RemoveDiacritics().Contains(@0)", cleanQuery);
Debug.Assert(results.Count() == 4);
}
}
//注册默认自定义类型处理程序
[动态链接类型]
公共静态类MyExtensions
{
//摘自:https://stackoverflow.com/questions/359827/ignoring-accented-letters-in-string-comparison/368850
公共静态字符串RemoveDiacritics(此字符串文本)
{
返回字符串.Concat(
text.Normalize(NormalizationForm.FormD)
.Where(ch=>CharUnicodeInfo.getunicodecegory(ch)=
单十分类。非间隔标记)
).规范化(NormalizationForm.FormC);
}
}
公共静态类条目
{
公共静态void Main(字符串[]args)
{
//你的意见
var query=“è”;
//使用扩展方法清理它
var cleanQuery=query.RemoveDiacritics();
//此演示的测试集
IQueryable testSet=新的EnumerableQuery(新列表()
{
“somè”、“tèst”、“sèt”、“BBeeBB”、“NoMatchHere”
});
var results=testSet.Where(“it.RemoveDiacritics().Contains(@0)”,cleanQuery);
Debug.Assert(results.Count()==4);
}
}
除非我从问题中了解到,否则linq查询是针对数据库运行的,而不是在内存中运行的。那么,这将是一个问题。但ToString和ToLower会如何工作呢?取决于linq提供者,这一点在讨论中没有提到。例如,对于实体框架,ToString()
可能被忽略,ToLower()
处理得很好(转换为适当的sql函数调用)。我使用的是实体框架是的,ToLower转换为适当的sql函数调用,是的……好的,更多(可能是次优的)解决方案是添加“可搜索的”字段,或在搜索前提取所有字段。“最佳”解决方案是在EF或任何OP使用的函数中进行修补。
// Registration for the default custom type handler
[DynamicLinqType]
public static class MyExtensions
{
// taken from: https://stackoverflow.com/questions/359827/ignoring-accented-letters-in-string-comparison/368850
public static string RemoveDiacritics(this string text)
{
return string.Concat(
text.Normalize(NormalizationForm.FormD)
.Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) !=
UnicodeCategory.NonSpacingMark)
).Normalize(NormalizationForm.FormC);
}
}
public static class Entry
{
public static void Main(string[] args)
{
// your input
var query = "éè";
// clean it using your extension method
var cleanQuery = query.RemoveDiacritics();
// a test set for this demo
IQueryable<string> testSet = new EnumerableQuery<string>(new List<string>()
{
"soméè", "tèèst", "séét", "BBeeBB", "NoMatchHere"
});
var results = testSet.Where("it.RemoveDiacritics().Contains(@0)", cleanQuery);
Debug.Assert(results.Count() == 4);
}
}