Reputation: 327
I am building the expression tree:
{x => x.principal_info.First().agent_for_property_info}
It works as expected.
In fact, I need to convert it to IEnumerable
instead of ICollection
as you can see here.
Here is the method that works:
public Expression<Func<T, IEnumerable<K>>> GetGenericExpression<T, K>(bool first = false, params string[] properties)
{
var expression = GetNavigationPropertySelector<T, K>(typeof(T), first, properties);
var expRight = (Expression<Func<T, IEnumerable<K>>>)expression;
return expRight;
}
In the expression, I get the valid lambda expression:
{x => x.principal_info.First().agent_for_property_info}
When I am casting:
var expRight = (Expression<Func<T, IEnumerable<K>>>)expression;
I get an exception:
Unable to cast object of
type
'System.Linq.Expressions.Expression`1[System.Func`2[SomeModel1,
System.Collections.Generic.ICollection`1[SomeModel]]]'
to type
'System.Linq.Expressions.Expression`1[System.Func`2[SomeModel1
,System.Collections.Generic.IEnumerable`1[SomeModel]]]'.
I knew that ICollection
inherits from IEnumerable
assuming, that it something pretty easy to fix.
I researched a lot but didn't find the solution how to cast ICollection<T>
to IEnumerable<T>
or if this even possible?
In fact, the compiler can cast it implicitly as these lines are valid:
var queryData1 = new QueryData<contact_info, IEnumerable<property_info>>()
{
WhereClause = expression,
SelectClause = info => info.principal_info.First().agent_for_property_info
};
As this expression is a type of ICollection
:
info => info.principal_info.First().agent_for_property_info
Upvotes: 5
Views: 2143
Reputation: 41
The solution here is to cast the result ICollection to IEnumerable:
Type resultType = typeof(IEnumerable<>).MakeGenericType(elementResultType);
UnaryExpression ienumerableResultExpression = Expression.MakeUnary(ExpressionType.Convert, resultExpr, resultType);
var result1 = Expression.Call(
typeof(Queryable), "Select", new Type[] { elementResultType, elementResultType },
resultProperty, ienumerableResultExpression );
The compiler seems to convert implicitly for you if you write out the Lambda, but it seems you have to explicitly cast if you use Expressions.
Upvotes: 0
Reputation: 327
After a few hours of researching, trying different approaches, I came up with Idea, trying to overcome this exception. So the workaround I use was the suggestion from the comments:
x => x.principal_info.First().agent_for_property_info.Select(x4 => x4)
Here what I have added while building an expression:
var result1 = Expression.Call(
typeof(Enumerable), "Select", new Type[] { elementResultType, elementResultType },
resultProperty, resultExpr);
I actually didn't find the solution, but if someone will encounter such problem, maybe this answer could save his time.
Upvotes: 1