Howto create a System.Linq.Expressions.Expression for Like

http://stackoverflow.com/questions/956743/howto-create-a-system-linq-expressions-expression-for-like

 http://trentacular.com/2010/08/linq-to-entities-wild-card-like-extension-method/

http://www.albahari.com/nutshell/predicatebuilder.aspx

6 down vote accepted

Something like:

static IEnumerable<T> WhereLike<T>( 
       
this IEnumerable<T> data, 
       
string propertyOrFieldName, 
       
string value) 
{ 
   
var param = Expression.Parameter(typeof(T), "x"); 
   
var body = Expression.Call( 
       
typeof(Program).GetMethod("Like", 
           
BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public), 
           
Expression.PropertyOrField(param, propertyOrFieldName), 
           
Expression.Constant(value, typeof(string))); 
   
var lambda = Expression.Lambda<Func<T, bool>>(body, param); 
   
return data.Where(lambda.Compile()); 
} 
static bool Like(string a, string b) { 
   
return a.Contains(b); // just for illustration 
} 

 


 

In terms of a Func<Expression,Expression,Expression>:

static Expression Like(Expression lhs, Expression rhs) 
{ 
   
return Expression.Call( 
       
typeof(Program).GetMethod("Like", 
           
BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public) 
           
,lhs,rhs); 
} 

 

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

 

posted @ 2011-04-20 14:03  永不言败  阅读(1712)  评论(0编辑  收藏  举报