2012-06-13 66 views
-2

我有以下聲明:LINQ其中具有可變

var itemsFromList = from item in ListItems 
        where item.Countries != null 
        select item; 

因此,我可以返回所有存在於國家(有些是空的)的值。 在同一名單上有例如城市等欄目,我必須將它更改爲:

var itemsFromList = from item in ListItems 
        where item.cities != null 
        select item; 

有沒有辦法使用相同的語句返回,要麼不爲空使用城市或國家變量有點像這樣:

var itemsFromList = from item in ListItems 
        where item.variable != null 
        select item; 
+4

'Variable'與列表中的單個項目有什麼關係? – Groo

+2

你的問題對我來說很不明確 - 你想達到什麼目的? – BrokenGlass

+0

什麼是變量?變量和ListItems之間的聯繫是什麼? – ken2k

回答

2

它看起來對我像變,就是要僅僅是一個變量,這是在以後的日期定義的。如果你真的想讓你的表情變得像這樣可以修改,你最好的選擇就是使用反射。

首先,您需要獲得對所需屬性的PropertyInfo的引用。您可以撥打Type.GetProperty(string name)來完成此操作。一旦你有了PropertyInfo的引用,你可以通過調用PropertyInfo.GetValue(Object obj, Object[] index)來獲得特定實例的值。

下面是創建LINQ查詢的示例,該查詢將只獲取指定屬性不爲null的項目。

// Declare this as a Generic method of Type T so that we can pass in a 
// List containing anything and easily get the appropriate Type object 
public static IEnumerable<T> SelectNonNull<T>(
    IEnumerable<T> ListItems, string propertyName) 
{ 
    IEnumerable<T> itemsFromList; 
    // Get a reference to the PropertyInfo for the property 
    // we're doing a null-check on. 
    PropertyInfo variable = typeof(T).GetProperty(propertyName); 
    if (variable == null) 
    { 
     // The property does not exist on this item type: 
     // just return all items 
     itemsFromList = from item in ListItems 
         select item; 
    } 
    else 
    { 
     itemsFromList = from item in ListItems 
         // GetValue will check the value of item's 
         // instance of the specified property. 
         where variable.GetValue(item, null) != null 
         select item; 
    } 
    return itemsFromList; 
} 

爲了得到你的問題的結果,然後你可以使用此功能,像這樣:

var NonNullCountries = SelectNonNull(ListItems, "Countries"); 
var NonNullCities = SelectNonNull(ListItems, "cities"); 

或者,我們可以把這個聲明爲一個擴展方法(像其他LINQ的方法),如所以:

public static IEnumerable<T> SelectNonNull<T>(
    this IEnumerable<T> source, 
    string propertyName) 
{ 
    PropertyInfo variable = typeof(T).GetProperty(propertyName); 
    if (variable == null) 
    { 
     // Specified property does not exist on this item type: 
     //just return all items 
     return from item in source 
       select item; 
    } 
    else 
    { 
     return from item in source 
       where variable.GetValue(item, null) != null 
       select item; 
    } 
} 

我們可以將多個呼叫鏈接在一起。舉例來說,如果你想過濾掉其中「城市」和「國家」是空的所有條目,你可以只使用下列內容:

var NonNullCitiesOrCountries = ListItems.SelectNonNull("Countries") 
             .SelectNonNull("cities"); 

注: SelectNonNull剛剛返回IEnuerable。您仍然需要枚舉它以查看查詢的結果。

2

你的問題很清楚,但let子句讓你擺脫子表達式的結果。可能這(?):

var itemsFromList = from item in ListItems 
        let Variable = item.Countries 
        where Variable != null 
        select item; 

我不知道這是什麼會真正實現。

我唯一的想法是,你不知道什麼Variable是在編譯時,並希望注入一些東西?

正如@DarenThomas所說,如果Variable實際上是Linq語句的外部,整個語句就會失效,因爲Variable在每次迭代中都不會改變。

0

如果我正確理解你的問題,你想用動態的東西替代硬編碼字段Country

在這種情況下,你需要聲明Variable(姑且稱之爲getNotNullField代替)作爲函數從ListItemobject

Func<ListItem, object> getNotNullField; 
if (...) { 
    getNotNullField = item => item.Countries; 
} else { 
    getNotNullField = item => item.SomeOtherField; 
} 

... 

var itemsFromList = from item in ListItems where getNotNullField(item) != null 
        select item;