2010-10-13 94 views
6

我有一個Linq擴展方法來動態地使用字符串值過濾Linq查詢。例如:query.WhereHelper("columName", ">", 1)。我可以使用許多不同的過濾器運算符,如GreaterThan或NotEqual等,但不是「Like」。沒有Expression.Like或Expression.StartsWith等。我如何在我的Expression樹中實現Like運算符?這裏是我的代碼:像表達式樹中的運算符

public static IQueryable<T> WhereHelper<T>(this IQueryable<T> source, string columnName, object value, string filterType) 
{ 
    ParameterExpression table = Expression.Parameter(typeof(T), ""); 
    Expression column = Expression.PropertyOrField(table, columnName); 
    Expression valueExpression = Expression.Convert(Expression.Constant(value), column.Type); 
    Expression where = null; 

    switch (filterType) 
    { 
     case "<": 
      where = Expression.LessThan(column, valueExpression); 
      break; 
     case "<=": 
      where = Expression.LessThanOrEqual(column, valueExpression); 
      break; 
     case "=": 
      where = Expression.Equal(column, valueExpression); 
      break; 
     case ">": 
      where = Expression.GreaterThan(column, valueExpression; 
      break; 
     case ">=": 
      where = Expression.GreaterThanOrEqual(column, valueExpression); 
      break; 
     case "<>": 
      where = Expression.NotEqual(column, valueExpression); 
      break; 
    } 

    Expression lambda = Expression.Lambda(where, new ParameterExpression[] { table }); 

    Type[] exprArgTypes = { source.ElementType }; 

    MethodCallExpression methodCall = Expression.Call(typeof(Queryable), 
                 "Where", 
                 exprArgTypes, 
                 source.Expression, 
                 lambda); 

    return (IQueryable<T>)source.Provider.CreateQuery<T>(methodCall); 

回答

7

你會使用Expression.Callstring.StartsWithstring.Containsstring.EndsWith等方法。消費代碼將其轉換回TSQL。請注意,對於LINQ-to-SQL,這裏還有一些輔助函數,但不適用於EF。

+1

的 「輔助函數」 我的意思是['SqlMethods'](http://msdn.microsoft.com/en-us/library/system。 data.linq.sqlclient.sqlmethods.aspx) - 特別是'Like()' – 2010-10-13 11:37:45

+1

關於EF的評論是不正確的。有[EntityFunctions](http://msdn.microsoft.com/en-us/library/system.data.objects.entityfunctions.aspx),這與L2S的'SqlMethods'類似。然而,EF中原生支持'EndsWith'和'Contains'等函數,並且不需要這樣的幫助器。 – 2010-10-13 13:15:47

+0

@克雷格謝謝;我不知道那個。 – 2010-10-13 13:29:52

6

可以定義LIKE表達如下,

var propertyName = "Firstname"; 
var propertyValue= "xxxx"; 

MethodInfo refmethod = typeof(string).GetMethod("Contains", new[] { typeof(string) }); 
var parameter = Expression.Parameter(typeof(T), "type"); 
var property = Expression.Property(parameter, propertyName); 
var value = Expression.Constant(propertyValue, typeof(string)); 
var containsMethodExp = Expression.Call(property, refmethod, value); 
+0

經過測試和正常工作,您節省了我的一天!謝謝! – GiveEmTheBoot 2014-05-15 12:18:22