2012-12-28 14 views
1

嗨我必須對泛型類應用過濾器。樣品等級如下表所示在屬性名稱爲字符串的模板列表上過濾

public class Sample<T> 
{ 
    List<T> sourceList = new List<T>(); 

    public void applyFilter(string propertyName , EnumOperator operator , object value) 
    { 

    } 
} 

在這裏,我想使用LINQ或動態LINQ來實現過濾器,但我沒有得到任何積極的方向來實現這一功能。

請給我一些積極的方向,以便我可以實現此功能。

謝謝。

+1

爲什麼你有一個泛型類的時候沒有做任何事情的通用? –

+0

你試過了什麼? –

+0

我已經採用泛型類,因爲我正在使用綁定T型數據源,其中數據來自不同的表格,我必須對其應用過濾器。 – Awadhendra

回答

4

我會建議返回一個過濾列表,而不是修改源,也是字符串「經營者」是一個C#的關鍵字,因此該方法的簽名可能是:

public List<T> ApplyFilter(string propertyName, EnumOperator operatorType, object value) 
{ 
    .... 
} 

,我假設EnumOperatorenum有這樣的價值觀:

public enum EnumOperator 
{ 
    Equal, 
    NotEqual, 
    Bigger, 
    Smaller 
} 

和你有一些方法來檢查,如果操作員的值是通過還是未通過測試,沿着線的東西:

public static class OperatorEvaluator 
{ 
    public static bool Evaluate(EnumOperator operatorType, object first, object second) 
    { 
    ... 
    } 
} 

鑑於這種情況,你可以這樣做:

public List<T> ApplyFilter(string propertyName , EnumOperator operatorType, object value) 
{ 
    PropertyInfo pi = typeof(T).GetProperty(propertyName); 
    List<T> result = sourceList.Where(item => { 
    var propValue = pi.GetValue(item, null); 
    return OperatorEvaluator.Evaluate(operatorType, propValue, value); 
    }).ToList(); 
    return result; 
} 

這就是說,你可以隨時使用LINQ的方法,而不是訴諸反射來過濾幾乎所有的東西。

0

您可以使用反射檢索屬性值,你可以在操作使用簡單switch語句來進行過濾:

public IEnumerable<T> ApplyFilter(string propertyName, EnumOperator op, object value) 
{ 
    foreach (T item in sourceList) 
    { 
     object propertyValue = GetPropertyValue(item, propertyName); 
     if (ApplyOperator(item, propertyValue, op, value) 
     { 
      yield return item; 
     } 
    } 
} 

private object GetPropertyValue(object item, string propertyName) 
{ 
    PropertyInfo property = item.GetType().GetProperty(propertyName); 
    //TODO handle null 
    return property.GetValue(); 
} 

private bool ApplyOperator(object propertyValue, EnumOperator op, object value) 
{ 
    switch (op) 
    { 
     case EnumOperator.Equals: 
      return propertyValue.Equals(value); 
     //TODO other operators 
     default: 
      throw new UnsupportedEnumException(op); 
    } 
} 

(的優化將是仰望PropertyInfo一旦外循環。)

1

在這裏,我給你一個樣品例如如何使用LINQ to落實List<T>項目篩選..

public class clsCountry 
{ 
    public string _CountryCode; 
    public string _CountryName; 
    // 
    public clsCountry(string strCode, string strName) 
    { 
     this._CountryCode = strCode; 
     this._CountryName = strName; 
    } 
    // 
    public string CountryCode 
    { 
     get {return _CountryCode;} 
     set {_CountryCode = value;} 
    } 
    // 
    public string CountryName 
    { 
     get { return _CountryName; } 
     set { _CountryName = value; } 
    } 
} 

現在,讓我們創建一個基於類clsCountry的對象列表,並將它們存儲在List<T>對象中。

List<clsCountry> lstCountry = new List<clsCountry>(); 
lstCountry.Add(new clsCountry("USA", "United States")); 
lstCountry.Add(new clsCountry("UK", "United Kingdom")); 
lstCountry.Add(new clsCountry("IND", "India")); 

接下來,我們將在List<T>對象lstCountry綁定到名爲drpCountry像作爲DropDownList控制:

drpCountry.DataSource = lstCountry; 
drpCountry.DataValueField = "CountryCode"; 
drpCountry.DataTextField = "CountryName"; 
drpCountry.DataBind(); 

現在,使用LINQ從lstCountry對象篩選數據並結合過濾列表下拉控件drpCountry。

var filteredCountries = from c in lstCountry 
         where c.CountryName.StartsWith("U") 
         select c; 

drpCountry.DataSource = filteredCountries; 
drpCountry.DataValueField = "CountryCode"; 
drpCountry.DataTextField = "CountryName"; 
drpCountry.DataBind(); 

現在下拉控制將只有2項

美國
英國

現在適用於你的情況下,這些技術..

2

帶有動態表達(如字符串)查詢,您可以通過微軟的Scott Gu使用Dynamic LINQ

Samples

它支持以下操作
1.選擇
2.凡
3排序依據
4.跳過
5.取
6的GroupBy

上述所有操作以字符串作爲參數。

它也有很小的表達語言(用於構建選擇器/謂詞/等),它非常易於使用。

例子:

var query = 
db.Customers. 
Where("City = @0 and Orders.Count >= @1", "London", 10). 
OrderBy("CompanyName"). 
Select("new(CompanyName as Name, Phone)"); 
相關問題