Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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# Like运算符或在LINQ to实体中使用通配符_C#_Linq_Linq To Entities - Fatal编程技术网

C# Like运算符或在LINQ to实体中使用通配符

C# Like运算符或在LINQ to实体中使用通配符,c#,linq,linq-to-entities,C#,Linq,Linq To Entities,我使用的是LINQ2实体。 问题如下: string str = '%test%.doc%' .Contains(str) // converts this into LIKE '%~%test~%.doc~%%' 预期转换:如“%test%.doc%” 如果是Linq2SQL,我可以使用SqlMethods,就像有人在我前面的问题中回答的那样。但现在由于我使用的是L2E而不是L2S,我需要其他解决方案。您可以尝试使用,作者介绍了如何使用LINQ to实体中的通配符构建LIKE语句 编辑:由

我使用的是LINQ2实体。 问题如下:

string str = '%test%.doc%' 
.Contains(str) // converts this into LIKE '%~%test~%.doc~%%'
预期转换:如“%test%.doc%”

如果是Linq2SQL,我可以使用SqlMethods,就像有人在我前面的问题中回答的那样。但现在由于我使用的是L2E而不是L2S,我需要其他解决方案。

您可以尝试使用,作者介绍了如何使用LINQ to实体中的通配符构建LIKE语句

编辑:由于原来的链接现在已失效,下面是原来的扩展类(根据)和用法示例

扩展名:

public static class LinqHelper
{
    //Support IQueryable (Linq to Entities)
    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));
    }

    //Support IEnumerable (Linq to objects)
    public static IEnumerable<TSource> WhereLike<TSource>(this IEnumerable<TSource> sequence, Func<TSource, string> expression, string value, char wildcard)
    {
        var regEx = WildcardToRegex(value, wildcard);

        //Prevent multiple enumeration:
        var arraySequence = sequence as TSource[] ?? sequence.ToArray();

        try
        {
            return arraySequence.Where(item => Regex.IsMatch(expression(item), regEx));
        }
        catch (ArgumentNullException)
        {
            return arraySequence;
        }
    }

    //Used for the IEnumerable support
    private static string WildcardToRegex(string value, char wildcard)
    {
        return "(?i:^" + Regex.Escape(value).Replace("\\" + wildcard, "." + wildcard) + "$)";
    }

    //Used for the IQueryable support
    private 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 = "Equals";

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

        var stringType = typeof(string);
        return stringType.GetMethod(methodName, new[] { stringType });
    }
}
string strEmailToFind = "%@yahoo.com"

IQueryable<User> myUsers = entities.Users.WhereLike(u => u.EmailAddress, strEmailToFind, '%');
公共静态类LinqHelper
{
//支持IQueryable(Linq到实体)
公共静态IQueryable WhereLike(此IQueryable源、表达式值选择器、字符串值、字符通配符)
{
返回source.Where(BuildLikeExpression(valueSelector,value,通配符));
}
//支持IEnumerable(Linq到对象)
公共静态IEnumerable WhereLike(此IEnumerable序列、Func表达式、字符串值、字符通配符)
{
var regEx=通配符toregex(值,通配符);
//防止多重枚举:
var arraySequence=作为TSource[]的序列?sequence.ToArray();
尝试
{
返回arraySequence.Where(item=>Regex.IsMatch(表达式(item),Regex));
}
捕获(异常)
{
返回序列;
}
}
//用于IEnumerable支持
私有静态字符串通配符toregex(字符串值,字符通配符)
{
返回“(?i:^”+Regex.Escape(value).Replace(“\\”+通配符,“.”+通配符)+“$”;
}
//用于可更换支架
私有静态表达式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=“等于”;
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”;
}
var stringType=typeof(字符串);
返回stringType.GetMethod(methodName,new[]{stringType});
}
}
用法示例:

public static class LinqHelper
{
    //Support IQueryable (Linq to Entities)
    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));
    }

    //Support IEnumerable (Linq to objects)
    public static IEnumerable<TSource> WhereLike<TSource>(this IEnumerable<TSource> sequence, Func<TSource, string> expression, string value, char wildcard)
    {
        var regEx = WildcardToRegex(value, wildcard);

        //Prevent multiple enumeration:
        var arraySequence = sequence as TSource[] ?? sequence.ToArray();

        try
        {
            return arraySequence.Where(item => Regex.IsMatch(expression(item), regEx));
        }
        catch (ArgumentNullException)
        {
            return arraySequence;
        }
    }

    //Used for the IEnumerable support
    private static string WildcardToRegex(string value, char wildcard)
    {
        return "(?i:^" + Regex.Escape(value).Replace("\\" + wildcard, "." + wildcard) + "$)";
    }

    //Used for the IQueryable support
    private 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 = "Equals";

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

        var stringType = typeof(string);
        return stringType.GetMethod(methodName, new[] { stringType });
    }
}
string strEmailToFind = "%@yahoo.com"

IQueryable<User> myUsers = entities.Users.WhereLike(u => u.EmailAddress, strEmailToFind, '%');
string strEmailToFind=“%@yahoo.com”
IQueryable myUsers=entities.Users.WhereLike(u=>u.EmailAddress,strEmailToFind,“%”);
或者,如果您希望用户更习惯于Windows资源管理器样式的通配符:

string strEmailToFind = "*@yahoo.com"

IQueryable<User> myUsers = entities.Users.WhereLike(u => u.EmailAddress, strEmailToFind, '*');
string strEmailToFind=“*@yahoo.com”
IQueryable myUsers=entities.Users.WhereLike(u=>u.EmailAddress,strEmailToFind,“*”);

使用正则表达式

下面将打印出当前目录中与test.doc*匹配的所有文件(dos通配符样式-我相信这就是您所要求的)

拆线

var str =  "%test%.doc%";
var arr = str.Split(new[]{'%'} ,StringSplitOptions.RemoveEmptyEntries);
var q = tblUsers.Select (u => u);
foreach (var item in arr)
{
    var localItem = item;
    q = q.Where (x => x.userName.Contains(localItem));
}

根据Magnus的正确答案,下面是一个可以重复使用的扩展方法,正如我在项目中需要的那样

public static class LinqExtensions
{
    public static Expression<Func<T, bool>> WildCardWhere<T>(this Expression<Func<T, bool>> source, Expression<Func<T, string>> selector, string terms, char separator)
    {
        if (terms == null || selector == null)
            return source;

        foreach (string term in terms.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries))
        {
            string current = term;
            source = source.And(
                Expression.Lambda<Func<T, bool>>(
                    Expression.Call(selector.Body, "Contains", null, Expression.Constant(current)),
                    selector.Parameters[0]
                )
            );
        }

        return source;
    }
}
公共静态类LinqExtensions
{
公共静态表达式通配符where(此表达式源、表达式选择器、字符串术语、字符分隔符)
{
如果(术语==null | |选择器==null)
返回源;
foreach(terms.Split中的字符串项(新[]{separator},StringSplitOptions.RemoveEmptyEntries))
{
字符串电流=术语;
来源=来源。和(
Lambda(
Expression.Call(selector.Body,“Contains”,null,Expression.Constant(current)),
选择器。参数[0]
)
);
}
返回源;
}
}
用法:

var terms = "%test%.doc%";
Expression<Func<Doc, bool>> whereClause = d => d;
whereClause = whereClause.WildCardWhere(d => d.docName, terms, '%');
whereClause = whereClause.WildCardWhere(d => d.someOtherProperty, "another%string%of%terms", '%');
var result = ListOfDocs.Where(whereClause).ToList();
var terms=“%test%.doc%”;
表达式whereClause=d=>d;
whereClause=whereClause.WildCardWhere(d=>d.docName,术语“%”);
whereClause=whereClause.WildCardWhere(d=>d.someOtherProperty,“另一个%string%的%terms”,“%”);
var result=ListOfDocs.Where(Where子句).ToList();

该扩展在上使用谓词生成器。结果sql对该表进行单表扫描,不管其中有多少项。Jo Vdb有一个扩展,如果您想改为使用iQueryable的扩展,您可以从它开始。

SQL方法PATINDEX提供了与LIKE相同的功能。因此,您可以使用以下方法:


所以我也在尝试同样的事情——尝试配对一个列表,返回所有匹配搜索词的候选人。我希望这样,如果用户键入“Arizona”,它将返回所有内容,而不管该案例是否包含Arizona。此外,如果用户键入“Arizona Cha”,它将返回“Arizona License Change”之类的项目。以下方面发挥了作用:

private List<Certification> GetCertListBySearchString()
    {
        string[] searchTerms = SearchString.Split(' ');
        List<Certification> allCerts = _context.Certifications.ToList();

        allCerts = searchTerms.Aggregate(allCerts, (current, thisSearchString) => (from ac in current
                                                                                   where ac.Name.ToUpper().Contains(thisSearchString.ToUpper())
                                                                                   select ac).ToList());
          return allCerts;
    }
private List GetCertListBySearchString()
{
string[]searchTerms=SearchString.Split(“”);
列出所有证书=_context.Certifications.ToList();
allCerts=searchTerms.Aggregate(allCerts,(当前,thisSearchString)=>(来自当前ac)
其中ac.Name.ToUpper()包含(thisSearchString.ToUpper())
选择ac.ToList());
返回所有证书;
}

我在前面看到过,它没有一个可以使用的示例,只有一个示例:entities.Table.WhereLike(el=>el.position,position,“%”)。所以你应该设置w