Like operator or using wildcards in LINQ to Entities

前端 未结 6 1345
抹茶落季
抹茶落季 2021-02-06 05:12

I\'m using LINQ 2 Entities. Following is the problem:

string str = \'%test%.doc%\' 
.Contains(str) // converts this into LIKE \'%~%test~%.doc~%%\'
6条回答
  •  暖寄归人
    2021-02-06 05:37

    You can try use this article, where author describes how to build a LIKE statement with wildcard characters in LINQ to Entities.

    EDIT: Since the original link is now dead, here is the original extension class (as per Jon Koeter in the comments) and usage example.

    Extension:

    public static class LinqHelper
    {
        //Support IQueryable (Linq to Entities)
        public static IQueryable WhereLike(this IQueryable source, Expression> valueSelector, string value, char wildcard)
        {
            return source.Where(BuildLikeExpression(valueSelector, value, wildcard));
        }
    
        //Support IEnumerable (Linq to objects)
        public static IEnumerable WhereLike(this IEnumerable sequence, Func 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> BuildLikeExpression(Expression> 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>(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 });
        }
    }
    

    Usage Example:

    string strEmailToFind = "%@yahoo.com"
    
    IQueryable myUsers = entities.Users.WhereLike(u => u.EmailAddress, strEmailToFind, '%');
    

    or, if you expect your users to be more accustomed to Windows Explorer-styled wildcards:

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

提交回复
热议问题