I'm currently trying to convert an
Expression<Func<T,object>>
to an
Expression<Func<T,bool>>
Currently the watch shows me that my expression holds
Expression<Func<T,object>> myExpression = model=>Convert(model.IsAnAirplane)
I'd like to simplify this to
Expression<Func<T,bool>> myExpression = model=>model.IsAnAirplane
Currently I only succeed at adding a convert, resulting in:
Expression<Func<T,bool>> myExpression = model=>Convert(Convert(model.IsAnAirplane))
But since the underlying type IS a bool, I should be able to scratch the converts entirely, right? I'm familiar with expression visitors etc, but still can't figure out how to remove the convert.
Edit: this accepted answer to this question Generic unboxing of Expression<Func<T, object>> to Expression<Func<T, TResult>> (that could be a possible duplicate) doesn't work for me ... as the expression gets translated by EF, you can see it does Convert(Convert()) instead of just removing the first convert... , this results in "Unable to cast the type 'System.Boolean' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types."
You should be able to strip out any Convert
wrappers using something like this:
Expression<Func<YourModel, object>> boxed = m => m.IsAnAirplane;
var unboxed = (Expression<Func<YourModel, bool>>)StripConvert(boxed);
// ...
public static LambdaExpression StripConvert<T>(Expression<Func<T, object>> source)
{
Expression result = source.Body;
// use a loop in case there are nested Convert expressions for some crazy reason
while (((result.NodeType == ExpressionType.Convert)
|| (result.NodeType == ExpressionType.ConvertChecked))
&& (result.Type == typeof(object)))
{
result = ((UnaryExpression)result).Operand;
}
return Expression.Lambda(result, source.Parameters);
}
If you prefer, you could alter StripConvert
to return Expression<Func<T,U>>
instead of a plain LambdaExpression
and perform the cast inside the method itself, but in that case you wouldn't be able to take advantage of type-inferencing for the method call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With