2011-07-08 69 views
1

我有一個winforms應用程序,基本上使用實體框架從數據庫加載一堆數據並將其顯示在gridview上。多個運行時過濾器的動態Linq查詢

對於這種情況,可以考慮綁定到GridView的實體是這一個:

public class Person 
{ 
    public string name; 
    public string sex; 
    public int age; 
} 

我想給用戶通過使用一系列的過濾器來過濾在GridView上的結果選項他可以選擇他想要過濾的列(年齡,性別,姓名),操作員(大於,等於,包含等)和值。

過濾器類將是這樣的:

public class filter 
{ 
    public string column; 
    public string operator; 
    public string value; 
} 

我的問題是:如何申請使用動態創建的LINQ查詢顯示在GridView上的過濾器中的數據?

回答

3

嘗試使用表達式樹動態生成lambda表達式對您的數據。

下面是一個示例實現:

void Main() 
{ 
    var fieldName = "LastName"; 
    var value = "test"; 

    var db = new List<Person>() { 
     new Person() { name = "fred jones", sex = "male", age = 55 }, 
     new Person() { name = "samantha jones", sex = "female", age = 45 }, 
     new Person() { name = "cindy jones", sex = "female", age = 6 } 
    }; 

    // single query 
    db.Where(Person.GetFilter("sex", "==", "female").Compile()).Dump(); 

    // OR example 
    db.Where( 
     PredicateBuilder.Or<Person>(
      Person.GetFilter("sex", "==", "male"), 
      Person.GetFilter("age", "<", 50) 
     ).Compile() 
    ).Dump(); 

} 
class Person 
{ 
    public string name; 
    public string sex; 
    public int age; 

    public static Expression<Func<Person,bool>> GetFilter<T>(string column, string @operator, T value) 
    { 
     var ops = new Dictionary<string, Func<Expression, Expression, Expression>>() { 
      { "==", (x,y) => Expression.Equal(x,y) }, 
      { "<=", (x,y) => Expression.LessThanOrEqual(x,y) }, 
      { ">=", (x,y) => Expression.GreaterThanOrEqual(x,y) }, 
      { ">", (x,y) => Expression.GreaterThan(x,y) }, 
      { "<", (x,y) => Expression.LessThan(x,y) }, 
     }; 

     var param = Expression.Parameter(typeof(Person)); 
     var deref = Expression.PropertyOrField(param, column); 
     var testval = Expression.Constant(value); 

     return Expression.Lambda<Func<Person,bool>>(
      ops[@operator](deref, testval), 
      param); 
    } 
} 

注意我用Linqpad測試這使更換使用.dump()有什麼在你的顯示數據的情況下相應的呼叫。它要求PredicateBuilder類構建OR或AND語句。如果錯誤類型作爲值參數傳遞(比較年齡時傳遞的字符串,例如,拋出「InvalidOperationException:未爲類型'System.String'和'System.Int32'定義二元運算符Equal' 「)。

如果有人能告訴我一個更好的方法來處理將一個運算符的字符串表示轉換爲Expression類,讓我知道,因爲我對上述方式並不滿意,但這是我能想到的最快在當時。