Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用通配符(如*,%,?)进行LINQ搜索,?_C# - Fatal编程技术网

C# 使用通配符(如*,%,?)进行LINQ搜索,?

C# 使用通配符(如*,%,?)进行LINQ搜索,?,c#,C#,您好,我有一个名称类型对象的集合,我想对其执行通配符搜索。例如,如果我提供搜索条件*ABC,则返回的名称应以ABC开头。如果我提供了搜索条件ABC*,那么返回的名称应以ABC结尾。如果我提供了搜索条件*ABC*,那么返回的名称应该包含ABC。如果我提供一个搜索条件,那么返回名称的第二、第三和第四个字符应该分别是ABC,第一个字符可以是任何字符。我认为您需要使用.Contains、.StartWith、.EndsWith我认为您需要Regex.Escape和Regex.IsMatch() priv

您好,我有一个名称类型对象的集合,我想对其执行通配符搜索。例如,如果我提供搜索条件
*ABC
,则返回的名称应以
ABC
开头。如果我提供了搜索条件
ABC*
,那么返回的名称应以
ABC
结尾。如果我提供了搜索条件
*ABC*
,那么返回的名称应该包含
ABC
。如果我提供一个搜索条件,那么返回名称的第二、第三和第四个字符应该分别是
ABC
,第一个字符可以是任何字符。

我认为您需要使用.Contains、.StartWith、.EndsWith

我认为您需要Regex.Escape和Regex.IsMatch()

private IEnumerable过滤器列表(IEnumerable列表,字符串查询)
{
字符串模式=QueryToRegex(查询);
其中(i=>Regex.IsMatch(i.Name,pattern,RegexOptions.Singleline));
}
私有静态字符串QueryToRegex(字符串查询)
{
返回“^”+Regex.Escape(查询)。替换(“\\*”,“*”)。替换(“\\?”,“)+“$”;
}

注意:更好的是他的正则表达式更好,所以可耻地在这里修复了它。

这里有一个扩展方法,您可以使用

public static class EnumerableExtensions
{
    public static IEnumerable<T> MatchesWildcard<T>(this IEnumerable<T> sequence, Func<T,string> expression, string pattern)
    {
        var regEx = WildcardToRegex(pattern);

        return sequence.Where(item => Regex.IsMatch(expression(item), regEx));
    }

    public static string WildcardToRegex(string pattern)
    {
        return "^" + Regex.Escape(pattern).
        Replace("\\*", ".*").
        Replace("\\?", ".") + "$";
    }
}
(WildcardToRegex摘自)

这列出了一个扩展方法,它也与实体框架和LINQ to实体兼容

用法示例:

var searchTerm = "*Inc";
var q = db.Customers
        .WhereLike(c => c.CompanyName, searchTerm, '*')
        .ToList();
源代码:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

    public static class LinqExtensions
    {
        public static IQueryable<TSource> WhereLike<TSource>(
            this IQueryable<TSource> source,
            Expression<Func<TSource, string>> valueSelector,
            string value,
            char wildcard)
        {
            return source.Where(BuildLikeExpression(valueSelector, value, wildcard));
        }

        public static Expression<Func<TElement, bool>> BuildLikeExpression<TElement>(
            Expression<Func<TElement, string>> valueSelector,
            string value,
            char wildcard)
        {
            if (valueSelector == null)
                throw new ArgumentNullException("valueSelector");

            var method = GetLikeMethod(value, wildcard);

            value = value.Trim(wildcard);
            var body = Expression.Call(valueSelector.Body, method, Expression.Constant(value));

            var parameter = valueSelector.Parameters.Single();
            return Expression.Lambda<Func<TElement, bool>>(body, parameter);
        }

        private static MethodInfo GetLikeMethod(string value, char wildcard)
        {
            var methodName = "Contains";

            var textLength = value.Length;
            value = value.TrimEnd(wildcard);
            if (textLength > value.Length)
            {
                methodName = "StartsWith";
                textLength = value.Length;
            }

            value = value.TrimStart(wildcard);
            if (textLength > value.Length)
            {
                methodName = (methodName == "StartsWith") ? "Contains" : "EndsWith";
                textLength = value.Length;
            }

            var stringType = typeof(string);
            return stringType.GetMethod(methodName, new Type[] { stringType });
        }
    }
使用系统;
使用System.Collections.Generic;
使用系统数据;
使用System.Data.Object;
使用System.Data.Objects.DataClass;
使用System.Linq;
使用System.Linq.Expressions;
运用系统反思;
公共静态类LinqExtensions
{
公共静态可在何处查询(
这是可靠的消息来源,
表达式值选择器,
字符串值,
字符(通配符)
{
返回source.Where(BuildLikeExpression(valueSelector,value,通配符));
}
公共静态表达式BuildLikeExpression(
表达式值选择器,
字符串值,
字符(通配符)
{
如果(valueSelector==null)
抛出新ArgumentNullException(“valueSelector”);
var方法=GetLikeMethod(值,通配符);
value=value.Trim(通配符);
var body=Expression.Call(valueSelector.body,方法,Expression.Constant(value));
var parameter=valueSelector.Parameters.Single();
返回表达式.Lambda(主体,参数);
}
私有静态MethodInfo GetLikeMethod(字符串值,字符通配符)
{
var methodName=“Contains”;
var textLength=value.Length;
value=value.TrimEnd(通配符);
如果(textLength>value.Length)
{
methodName=“StartsWith”;
textLength=value.Length;
}
value=value.TrimStart(通配符);
如果(textLength>value.Length)
{
methodName=(methodName=“StartWith”)?“包含”:“EndsWith”;
textLength=value.Length;
}
var stringType=typeof(字符串);
返回stringType.GetMethod(methodName,新类型[]{stringType});
}
}

我们在这里谈论的是LINQ对对象,还是LINQ对SQL?@Samuel:看起来像是LINQ对对象,因为他提到他有一个“对象集合”.你的正则表达式方法(你复制的,我从头顶键入的)比我的好。@ErikHeemskerk-当你有谷歌的时候,为什么还要麻烦学习正则表达式语法呢?:-)啊,但无论如何这都是徒劳的,因为塞缪尔·杰克发布了一个更好的方法来将通配符表达式翻译成正则表达式;我的工作不正常。
var searchTerm = "*Inc";
var q = db.Customers
        .WhereLike(c => c.CompanyName, searchTerm, '*')
        .ToList();
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

    public static class LinqExtensions
    {
        public static IQueryable<TSource> WhereLike<TSource>(
            this IQueryable<TSource> source,
            Expression<Func<TSource, string>> valueSelector,
            string value,
            char wildcard)
        {
            return source.Where(BuildLikeExpression(valueSelector, value, wildcard));
        }

        public static Expression<Func<TElement, bool>> BuildLikeExpression<TElement>(
            Expression<Func<TElement, string>> valueSelector,
            string value,
            char wildcard)
        {
            if (valueSelector == null)
                throw new ArgumentNullException("valueSelector");

            var method = GetLikeMethod(value, wildcard);

            value = value.Trim(wildcard);
            var body = Expression.Call(valueSelector.Body, method, Expression.Constant(value));

            var parameter = valueSelector.Parameters.Single();
            return Expression.Lambda<Func<TElement, bool>>(body, parameter);
        }

        private static MethodInfo GetLikeMethod(string value, char wildcard)
        {
            var methodName = "Contains";

            var textLength = value.Length;
            value = value.TrimEnd(wildcard);
            if (textLength > value.Length)
            {
                methodName = "StartsWith";
                textLength = value.Length;
            }

            value = value.TrimStart(wildcard);
            if (textLength > value.Length)
            {
                methodName = (methodName == "StartsWith") ? "Contains" : "EndsWith";
                textLength = value.Length;
            }

            var stringType = typeof(string);
            return stringType.GetMethod(methodName, new Type[] { stringType });
        }
    }