private LambdaExpression GetLambdaForSimpleProperty <T>(IncludePathMetadataFragment includePathMetadataFragment, LambdaExpression filterLambda) { var lambdaType = typeof(Func <,>).GetGenericTypeDefinition().MakeGenericType(includePathMetadataFragment.DeclaringType, includePathMetadataFragment.PropertyType); var rootParameter = Expression.Parameter(includePathMetadataFragment.DeclaringType); var propertyLambda = Expression.Lambda(lambdaType, includePathMetadataFragment.PropertyAccessExpression, rootParameter); return(ParameterToMemberExpressionRebinder.CombineSinglePropertySelectorWithPredicate(propertyLambda, filterLambda)); }
/// <summary> /// Modifies an expression, rebinding the usage of parameter x to the usage of a property on parameter x. /// </summary> /// <param name="propertySelector">The expression to replace the original parameter with.</param> /// <param name="propertyPredicate">The predicate built on the original parameter.</param> /// <returns>A predicate on the rebound root expression.</returns> public static LambdaExpression CombineSinglePropertySelectorWithPredicate( LambdaExpression propertySelector, LambdaExpression propertyPredicate) { var memberExpression = propertySelector.Body as MemberExpression; var containingType = memberExpression.Member.DeclaringType; if (memberExpression == null) { throw new ArgumentException("propertySelector"); } var rootPredicateType = typeof(Func <,>).GetGenericTypeDefinition().MakeGenericType(containingType, typeof(bool)); var expr = Expression.Lambda(rootPredicateType, propertyPredicate.Body, propertySelector.Parameters); var rebinder = new ParameterToMemberExpressionRebinder(propertyPredicate.Parameters[0], memberExpression); expr = (LambdaExpression)rebinder.Visit(expr); return(expr); }