2010-03-24 155 views
4

更新使用表達式樹

多虧了馬克的幫助下AlphaPagedList類is now available on CodePlex如果有人有興趣生成LINQ查詢

原始

我試圖創建一個表達式樹返回以給定字符集開頭的元素。

IList<char> chars = new List<char>{'a','b'}; 
IQueryable<Dept>Depts.Where(x=> chars.Contains(x.DeptName[0])); 

我想這是任何IEnumerable的使用,我提供了一個lamdba的財產就如選擇:

Depts.Alpha(x=>x.DeptName, chars);

我一直想這一點,但沒有運氣可言,有什麼幫助?

public static IQueryable<T> testing<T>(this IQueryable<T> queryableData, Expression<Func<T,string>> pi, IEnumerable<char> chars) 
{ 
// Compose the expression tree that represents the parameter to the predicate. 

ParameterExpression pe = Expression.Parameter(queryableData.ElementType, "x"); 
ConstantExpression ch = Expression.Constant(chars,typeof(IEnumerable<char>)); 
// ***** Where(x=>chars.Contains(x.pi[0])) ***** 
// pi is a string property 
//Get the string property 

Expression first = Expression.Constant(0); 
//Get the first character of the string 
Expression firstchar = Expression.ArrayIndex(pi.Body, first); 
//Call "Contains" on chars with argument being right 
Expression e = Expression.Call(ch, typeof(IEnumerable<char>).GetMethod("Contains", new Type[] { typeof(char) }),firstchar); 


MethodCallExpression whereCallExpression = Expression.Call(
    typeof(Queryable), 
    "Where", 
    new Type[] { queryableData.ElementType }, 
    queryableData.Expression, 
    Expression.Lambda<Func<T, bool>>(e, new ParameterExpression[] { pe })); 
// ***** End Where ***** 

return (queryableData.Provider.CreateQuery<T>(whereCallExpression)); 
} 

回答

2

喜歡的東西(重新閱讀的問題後可進行編輯) - 但請注意,Expression.Invoke不3.5SP1在EF工作(但它是罰款的LINQ到SQL):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Linq.Expressions; 

class Dept 
{ 
    public string DeptName { get; set; } 
} 
public static class Program 
{ 
    static void Main() 
    { 
     IList<char> chars = new List<char>{'a','b'}; 
     Dept[] depts = new[] { new Dept { DeptName = "alpha" }, new Dept { DeptName = "beta" }, new Dept { DeptName = "omega" } }; 
     var count = testing(depts.AsQueryable(), dept => dept.DeptName, chars).Count(); 
    } 

    public static IQueryable<T> testing<T>(this IQueryable<T> queryableData, Expression<Func<T,string>> pi, IEnumerable<char> chars) 
    { 
     var arg = Expression.Parameter(typeof(T), "x"); 
     var prop = Expression.Invoke(pi, arg); 
     Expression body = null; 
     foreach(char c in chars) { 
      Expression thisFilter = Expression.Call(prop, "StartsWith", null, Expression.Constant(c.ToString())); 
      body = body == null ? thisFilter : Expression.OrElse(body, thisFilter); 
     } 
     var lambda = Expression.Lambda<Func<T, bool>>(body ?? Expression.Constant(false), arg); 
     return queryableData.Where(lambda); 
    } 
} 
+0

非常完美,非常感謝。我正在處理一個字母數字分頁列表(沿着IPagedList的方向),這是非常寶貴的。 – Chao 2010-03-25 09:52:48