Reputation: 1433
I'm attempting to generate a dynamic expression that can order a list of ExpandoObjects. I don't know what will be in the expandoobjects (string, int, decimal, datetime, etc).
Unfortunately, it appears that if a null value is in the list when doing an orderby, an exception is thrown. I could remove the null values from my collection prior to sorting with a Where method, but I want to keep the null rows in the results returned.
What I was trying to do was generate an If Else statement, something like:
x => x.Item["Key"] != null ? x.Item["Key] : defaultvaluefortype
Here's my code snippet:
if (type == typeof (ExpandoObject))
{
arg = Expression.Parameter(typeof (T), "x");
expr = arg; //Get type of T
var first = (IDictionary<string, object>) source.First();
//Match the case of the string to the correct key value.
var propval =
first.Keys.First(x => String.Equals(x, prop, StringComparison.CurrentCultureIgnoreCase));
var key = Expression.Constant(propval, typeof(string));
ParameterExpression dictExpr = Expression.Parameter(typeof(IDictionary<string, object>));
var indexer = dictExpr.Type.GetProperty("Item");
var exprkeyed = Expression.Property(expr, indexer, key);
//Generates x.Item["KeyString"] so I can access the object.
expr = exprkeyed;
var Null = Expression.Constant(null);
expr = Expression.NotEqual(expr, Null);
expr = Expression.Condition(expr, exprkeyed, Expression.Constant(false)); //what do I return as the else?
type = typeof(Object);
}
Unfortunately, if I try to set a default based on the key type, I get an exception that the return values from my if/else don't match (ie; one is system.object, one is system.datetime). I believe the default value for object is null as well, so that's not the best.
Is there a way to do this without using a where statement to remove the null entries first? Maybe something I could return on the else that's like a skip or a sortlow/high?
Thanks for your time.
Upvotes: 1
Views: 989
Reputation: 66
You would return a Expression.Default(typeof(T))
.
In your code you change
expr = Expression.Condition(expr, exprkeyed, Expression.Default(typeof(T)));
Upvotes: 2