views:

837

answers:

3

I have a list of objects that I am trying to bind to a listview. I am sorting by two properties. The problem exists whereby some records may not have one of the properties. This is causing an error. I would like it to still bind the records that have the property.

IEnumerable<ERec> list = retailerList.Cast<ERec>();
lvwRetailStores.DataSource = list.OrderByDescending(r => r.Properties["RS_Partner Type"].ToString())
                                 .ThenBy(r => r.Properties["RS_Title"].ToString());
+2  A: 
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());

Or instead of != null, use whatever test the Properties collection has.

Adam Ruth
A: 

You can use a ternary expression in the 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());
Serguei
I should note, once the lambdas start getting that long it's a good idea anyway to declare them as functions to clean up the code.
Serguei
A: 

Another common approach is to give the collection a suitable default value, and return that when the collection doesn't have a particular key. For instance, if Properties implements 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());
outis