2009-11-09 12 views
6

Ho una lista di oggetti che sto cercando di associare ad un listview. Sto selezionando da due proprietà. Il problema esiste in base al quale alcuni record potrebbero non avere una delle proprietà. Questo sta causando un errore. Mi piacerebbe che legasse ancora i record che hanno la proprietà.Verificare se la proprietà è null nell'espressione lambda

IEnumerable<ERec> list = retailerList.Cast<ERec>(); 
lvwRetailStores.DataSource = list.OrderByDescending(r => r.Properties["RS_Partner Type"].ToString()) 
           .ThenBy(r => r.Properties["RS_Title"].ToString()); 
+0

Volete che i record manchino alla proprietà all'inizio o alla fine della lista ordinata? – outis

risposta

7
list.Where(r => r.Properties["RS_Partner_Type"] != null && r.Properties["RS_Title"] != null) 
    .OrderByDescending(r => r.Properties["RS_Partner Type"].ToString()) 
    .ThenBy(r => r.Properties["RS_Title"].ToString()); 

O invece di! = Null, qualunque sia l'uso di test Properties ha.

0

è possibile utilizzare un'espressione ternaria nel lambda:

list.OrderByDescending(r => r.Properties["RS_Partner_Type"] == null ? null : r.Properties["RS_Partner Type"].ToString()) 
    .ThenBy(r => r.Properties["RS_Title"] == null ? null : r.Properties["RS_Title"].ToString()); 
+0

Devo notare, una volta che i lambda iniziano a ricevere così tanto tempo, è comunque una buona idea dichiararli come funzioni per ripulire il codice. – Serguei

0

Un altro approccio comune è quello di dare alla collezione un valore predefinito adatto, e ritorno che, quando la raccolta non ha un determinato tasto. Per esempio, se Properties implementa IDictionary,

public static class IDictionaryExtension { 
    public static TValue GetValue<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key, TValue default) { 
     TValue result; 
     return dict.TryGetValue(key, out result) ? result : dflt; 
    } 
} 
... 
lvwRetailStores.DataSource = list.OrderByDescending(r => r.GetValue("RS_Partner Type", "").ToString()) 
           .ThenBy(r => r.GetValue("RS_Title","").ToString()); 
1

ho trovato che l'?? L'operatore funziona bene. Io uso parentesi a valutare per nulla,

Per esempio:

Datetime? Today = DateTimeValue // Check for Null, if Null put Today's date datetime GoodDate = Today ?? DateTime.Now

Questa stessa logica funziona in Lambda, basta usare le parentesi per garantire che i confronti corretti vengono utilizzati.

Problemi correlati