C# 动态LINQ不区分重音的字符串查询

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

我正在开发一个C#.Net MVC应用程序,并试图实现一种通用的实体字段搜索方法。随着我们的页面不断增长,我不想在每次添加新页面时编写搜索方法

为此,我正在使用Dynamic.Core LINQ查询:请访问: 我实现它的方式如下:在视图中的用户输入时,应用程序向控制器发送一个ajax请求,告诉它搜索该特定值,然后显示上一个值所在的新列表

问题是:我可以使它不区分大小写,但不区分重音,我想知道是否有人可以帮助我做到这一点

这是我的密码:

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);
        }
    }