2013-06-24 27 views
1

更常見的問題,但我怎麼寫LINQ Lambda表達式,以便它們將返回一個默認字符串或者只是一個空字符串,如果LINQ表達式失敗或不返回任何內容。在XSLT XPath中,如果匹配失敗,那麼只是沒有任何東西,應用程序沒有崩潰,而在LINQ中,似乎有異常。我該如何讓LINQ Lambda表達式像XPath一樣優雅地失敗?

我使用First()並嘗試FirstOrDefault()。

所以例如查詢可能是:

Customers.First(c=>c.id==CustId).Tasks.ToList(); 

Customers.Where(c=>c.id==CustId).ToList(); 

Model.myCustomers.Where(c=>c.id==CustId); 

無論查詢,如果不返回任何記錄或空那麼是否有基因? ral的方法來確保查詢失敗優雅?

謝謝。

+0

實在沒有辦法,除非你編寫自己的擴展方法。空處理只是當今大多數語言中最可怕的事情之一。 – Jacob

回答

1

當您訪問屬性時,C#中沒有任何優雅內容用於傳播空值。你可以創建自己的擴展方法:

public static class Extensions 
{ 
    public static TValue SafeGet<TObject, TValue>(
     this TObject obj, 
     Func<TObject, TValue> propertyAccessor) 
    { 
     return obj == null ? default(TValue) : propertyAccessor(obj); 
    } 

    public static IEnumerable<T> OrEmpty<T>(this IEnumerable<T> collection) 
    { 
     return collection ?? Enumerable.Empty<T>(); 
    } 
} 

像這樣來使用:

Customers.FirstOrDefault(c => c.id==CustId).SafeGet(c => c.Tasks).OrEmpty().ToList(); 
+0

這看起來很有趣。謝謝。 「Model.myCustomers.First(c => c.id == CustId).Name」將如何使用您的代碼查看? – SamJolly

+0

'Model.myCustomers.FirstOrDefault(c => c.id == CustId).SafeGet(c => c.Name)' – Jacob

+0

謝謝,這就是我正在尋找的,處理空列表和空值的通用方法值。非常感謝您的幫助,謝謝。 – SamJolly

0

唯一查詢我希望拋出一個異常會是第一個(假設Customers是一個有效的收集和NOT NULL本身):

Customers.First(c=>c.id==CustId).Tasks.ToList(); 

這將拋出一個異常,如果沒有客戶與idCustId(您的財產和變量名稱有一些套管問題)。

如果你不想拋出異常的不匹配,然後使用FirstOrDefault你提到,做一個空檢查,e.g:如果沒有匹配的記錄

var customer = Customers.FirstOrDefault(c => c.id == CustId); 
if (customer == null) 
{ 
    // deal with no match 
    return; 
} 

var taskList = customer.Tasks.ToList(); 
+0

感謝您的幫助。所以你必須打破LINQ查詢?我希望有一種表達方式。 – SamJolly

+0

你可以使用擴展方法(或簡單的老式的靜態幫助器方法),但很可能你會想要分解代碼,因爲你可能希望檢測到沒有匹配並分支代碼來調用你的不同表示邏輯表示層。 – devdigital

1

Customers.First(c=>c.id==CustId)會崩潰。

有幾種方法可以嘗試找到它,如果您使用FirstOrDefault,如果找不到匹配項則返回NULL,您可以檢查NULL

或者,您可以使用.Any語法檢查是否有任何記錄並返回boolean

+0

謝謝,任何()看起來很有趣。 – SamJolly