I’m trying to combine the following expressions into a single expression: item => item.sub, sub => sub.key to become item => item.sub.key. I need to do this so I can create an OrderBy method which takes the item selector separately to the key selector. This can be accomplished using one of the overloads on OrderBy and providing an IComparer<T>, but it won’t translate to SQL.
Following is a method signature to further clarify what I am trying to achive, along with an implementation that doesn’t work, but should illustrate the point.
public static IOrderedQueryable<TEntity> OrderBy<TEntity, TSubEntity, TKey>( this IQueryable<TEntity> source, Expression<Func<TEntity, TSubEntity>> selectItem, Expression<Func<TSubEntity, TKey>> selectKey) where TEntity : class where TSubEntity : class { var parameterItem = Expression.Parameter(typeof(TEntity), 'item'); ... some magic ... var selector = Expression.Lambda(magic, parameterItem); return (IOrderedQueryable<TEntity>)source.Provider.CreateQuery( Expression.Call(typeof(Queryable), 'OrderBy', new Type[] { source.ElementType, selector.Body.Type }, source.Expression, selector )); }
which would be called as:
.OrderBy(item => item.Sub, sub => sub.Key)
Is this possible? Is there a better way? The reason I want an OrderBy method that works this way is to support a complex key selection expression that applies to many entities, though they are exposed in different ways. Also, I’m aware of a way to do this using String representations of deep properties, but I’m trying to keep it strongly typed.
Since this is LINQ-to-SQL, you can usually use
Expression.Invoketo bring a sub-expression into play. I’ll see if I can come up with an example (update: done). Note, however, that EF doesn’t support this – you’d need to rebuild the expression from scratch. I have some code to do this, but it is quite lengthy…The expression code (using
Invoke) is quite simple:Here’s example usage on Northwind:
With TSQL (reformatted to fit):