2012-11-21 46 views
0

我有一個Product類的幾個屬性:更換開關情況來選擇類屬性與LINQ和反射C#過濾

public class Product 
{ 
    public int id { get; set; } 
    public string Name { get; set; } 
    public string Category { get; set; } 
    public string ProdCountry { get; set; } 
} 

現在假設我有var products = List<Product>,我想過濾某些特定的屬性值,我事先不知道。所有{ propertyName, propertyValue }雙必須匹配(SO和關係):

Dictionary<string, string> properties = GetPropertiesFromClient(); //Key = propertyName, Value = propertyValue 

List<Product> products = GetProductList(); 

foreach(var property in properties) 
{ 
    switch (property.Key) 
    { 
     case "Name": products = products.Where(p => p.Name == property.Value); 
        break; 

     case "Category": products = products.Where(p => p.Category == property.Value); 
         break; 

     case "ProdCountry": products = products. Where(p => p.ProdCountry == property.Value); 
          break; 
    } 
} 

的方法GetPropertiesFromClient()總是返回Dictionary<string, string>,我事先沒有財產,有多少存儲哪知道做。

有什麼捷徑可以避免我使用switch case?喜歡的東西:

foreach(var property in properties) 
{ 
    products = products.Where(t => t.GetType().GetProperty(property.Key).GetValue(t, null) == property.Value); 
} 

此代碼應該工作(邏輯),但我得到一個異常:

LINQ到實體不承認System.Object的 的GetValue方法」(System.Object的, System.Object [])'方法,並且此方法 無法轉換爲商店表達式。

我該如何實現我的目標?

+2

你的錯誤提示'products'是'名單'的'IQueryable的'代替。這是什麼? – Lee

+0

LINQ to Entities無法通過反射將屬性值轉換爲有效的SQL表達式。所以,你無法用反思來實現你的目標。嘗試動態構建EntitySQL或LINQ表達式。 – J0HN

+0

是的,它是一個IQueryable CiccioMiami

回答

0

由於property是一個對象,它試圖將get訪問器轉換爲SQL。

嘗試在本地執行getter並保存結構值。然後用局部變量,而不是屬性對象進行比較:

foreach(var property in properties) 
{ 
    var x = property.Value; 
    switch (property.Key) 
    { 
     case "Name": products = products.Where(p => p.Name == x); 
        break; 
     //... 
    } 
}