/// <summary> /// Adds another expression filter to original expression using Or operator /// </summary> /// <typeparam name="T">Type of object in the main filter</typeparam> /// <param name="expr1">Main filter expression</param> /// <param name="expr2">Additional filter expression on the same type of object as the main expression</param> /// <returns></returns> public static Expression <Func <T, bool> > Or <T>( this Expression <Func <T, bool> > expr1, Expression <Func <T, bool> > expr2 ) { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); return(Expression.Lambda <Func <T, bool> >(Expression.Or(left, right), parameter)); }
/// <summary> /// Adds another expression filter to original expression using Or operator /// </summary> /// <typeparam name="T">Type of object in the main filter</typeparam> /// <typeparam name="TNav">Type of the navigation property (can be deeply nested)</typeparam> /// <param name="expr1">Main filter expression</param> /// <param name="expr2">Filter expression that filters on the navigated property</param> /// <param name="navigationProperty">Expression to the navigation property (eg e => e.PropA.PropB) </param> /// <returns></returns> public static Expression <Func <T, bool> > Or <T, TNav>( this Expression <Func <T, bool> > expr1, Expression <Func <TNav, bool> > expr2, Expression <Func <T, TNav> > navigationProperty ) { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var navVisitor = new ReplaceExpressionVisitor(navigationProperty.Parameters[0], parameter); var nav = navVisitor.Visit(navigationProperty.Body); // Reset the navigation prop expression to start from the shared parameter var right = Expression.Invoke(expr2, nav); // Create an expression that navigates to the property return(Expression.Lambda <Func <T, bool> >(Expression.Or(left, right), parameter)); }