2013-02-05 121 views
-1

我想使用LINQ-to-objects來查詢深度幾個級別的對象集合來提取值。例如,給定一個實體對象我想,如果一個標誌被設置爲1以使EMAILADDRESS字符串,否則返回null:LINQ to Objects查詢忽略層次結構中的空對象

Entity.CommunicationCollection.Communication.CommunicationDetail.EmailAddress 

凡CommunicationDetail看起來是這樣的:

public class CommunicationDetail 
{ 
    public int Flag; 
    public string EmailAddress; 
} 

我想出了查詢看起來像這樣:

string email = Entity.CommunicationCollection.FirstOrDefault(x => x.Communication.CommunicationDetail.Flag == 1).EmailAddress; 

這樣做的問題是層次結構中的任何空對象都會導致null ref異常。有沒有辦法構建查詢以某種方式忽略空值,而不是首先檢查每個對象? (以上是一個簡化的例子,我正在研究的項目中的嵌套更加深入。)

+0

您當前的代碼將無法編譯 - 我懷疑你想''==而不是'='。 –

+0

快速回答:不。你必須自己檢查空值。 –

+0

另外,如果沒有與條件匹配的對象,FirstOrDefault()將返回null。因此,除非你100%確定它實際上會返回一些東西,否則執行'.FirstOrDefault(xxx).Something'本身就是危險的。 –

回答

3

那麼,您必須檢查所有內容或使用??進行違約,這仍然會很尷尬。我懷疑你想要的東西,如:

var email = Entity.CommunicationCollection 
        .Where(x => x.Communication != null && 
           x.Communication.CommunicationDetail != null && 
           x.Communication.CommunicationDetail.Flag == 1) 
        .Select(x => x.Communication.CommunicationDetail.EmailAddress) 
        .FirstOrDefault(); 

注意email仍然可以null這裏...

顯然,如果x.Communication不能爲空,或者x.Communication.CommunicationDetail不能爲空,你可以刪除這些檢查 - 目前尚不清楚在你的模型中可能爲空。

1

我強烈建議用一種叫做IsNull或IsNotNull的泛型方法創建一個類,並允許它接受任何對象類型並檢查該對象是否爲空。這將使你不必有單獨的驗證每個對象的所查詢

public class NullChecker where T : class 
{ 
    public static bool IsNotNull<T>(default(T) type) 
    { 
     return type != null; 
    } 
} 
+1

您需要'where T:class'才能編譯,除非您將其與'default(T)'進行比較。除非使用'default(T)',否則它也不適用於可空結構。 – Servy

+0

不知道我明白的好處..這只是意味着用NullChecker.IsNotNull(myObj)到處替換myObj!= null嗎? –

+0

我更喜歡它的可讀性。 – Robert