diff --git a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicQueryable.cs b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicQueryable.cs index b31b5f652c..cd7920156c 100644 --- a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicQueryable.cs +++ b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicQueryable.cs @@ -2100,6 +2100,7 @@ namespace System.Linq.Dynamic innerRight = Expression.Convert(invokedExpr, (left as MemberExpression).Type); } } + bool sequenceEqual = false; if (leftIsLambda && rightIsLambda) { { @@ -2109,6 +2110,7 @@ namespace System.Linq.Dynamic Type[] rightTypeGenericArguments = rightType.GetGenericArguments(); if (leftTypeGenericArguments.SequenceEqual(rightTypeGenericArguments)) { + sequenceEqual = true; if (leftTypeGenericArguments.Length == 2) { Type TOut = leftTypeGenericArguments[1]; @@ -2124,6 +2126,84 @@ namespace System.Linq.Dynamic } } + else + { + if (leftTypeGenericArguments.Length == 2) + { + //sequence not equal - could be Func && Func + if (leftTypeGenericArguments.First() == rightTypeGenericArguments.First()) + { + bool leftIsObject = leftTypeGenericArguments.ElementAt(1) == typeof(object); + bool rightIsObject = rightTypeGenericArguments.ElementAt(1) == typeof(object); + //if one is an object but not the other + if (leftIsObject ^ rightIsObject) + { + if (leftIsObject) + { + //left side is object + if (innerLeft == null) + { + parameters = new ParameterExpression[(left as LambdaExpression).Parameters.Count]; + (left as LambdaExpression).Parameters.CopyTo(parameters, 0); + innerLeft = Expression.Invoke(left, parameters); + } + unboxedLeft = Expression.Unbox(innerLeft, rightTypeGenericArguments.ElementAt(1)); + + //left is invoked and unboxed to right's TOut, right was not boxed + if (expressionType == ExpressionType.AndAlso) + { + return PredicateBuilder.And(right as Expression>, Expression.Lambda>(unboxedLeft, parameters) as Expression>); + } + if (expressionType == ExpressionType.OrElse) + { + return PredicateBuilder.And(right as Expression>, Expression.Lambda>(unboxedLeft, parameters) as Expression>); + } + } + else + { + //right side is object + if (innerRight == null) + { + parameters = new ParameterExpression[(right as LambdaExpression).Parameters.Count]; + (right as LambdaExpression).Parameters.CopyTo(parameters, 0); + innerRight = Expression.Invoke(right, parameters); + } + unboxedRight = Expression.Unbox(innerRight, leftTypeGenericArguments.ElementAt(1)); + + //right is invoked and unboxed to left's TOut, left was not boxed + if (expressionType == ExpressionType.AndAlso) + { + return PredicateBuilder.And(left as Expression>, Expression.Lambda>(unboxedRight, parameters) as Expression>); + } + if (expressionType == ExpressionType.OrElse) + { + return PredicateBuilder.And(left as Expression>, Expression.Lambda>(unboxedRight, parameters) as Expression>); + } + } + + + ////if op is and/or + //leftType = ((LambdaExpression)innerLeft ?? left).Type; + //rightType = ((LambdaExpression)innerRight ?? right).Type; + //leftTypeGenericArguments = leftType.GetGenericArguments(); + //rightTypeGenericArguments = rightType.GetGenericArguments(); + //Type leftTOut = leftTypeGenericArguments[1]; + //Type rightTOut = leftTypeGenericArguments[1]; + + //if (expressionType == ExpressionType.AndAlso) + //{ + // return PredicateBuilder.And(left as Expression>, right as Expression>); + //} + //if (expressionType == ExpressionType.OrElse) + //{ + // return PredicateBuilder.Or(left as Expression>, right as Expression>); + //} + + + } + } + } + } } } @@ -2132,6 +2212,11 @@ namespace System.Linq.Dynamic //left is a lambda, but the right was an unhandled expression type //!ConstantExpression, !MemberExpression //make sure the left gets invoked + if (parameters == null) + { + parameters = new ParameterExpression[(left as LambdaExpression).Parameters.Count]; + (left as LambdaExpression).Parameters.CopyTo(parameters, 0); + } innerLeft = Expression.Invoke(left, parameters); } if (rightIsLambda && innerRight == null) @@ -2139,6 +2224,11 @@ namespace System.Linq.Dynamic //right is a lambda, but the left was an unhandled expression type //!ConstantExpression, !MemberExpression //make sure the right gets invoked + if (parameters == null) + { + parameters = new ParameterExpression[(right as LambdaExpression).Parameters.Count]; + (right as LambdaExpression).Parameters.CopyTo(parameters, 0); + } innerRight = Expression.Invoke(right, parameters); } if (leftIsLambda && !rightIsLambda && innerLeft != null && !(innerLeft is UnaryExpression) && innerLeft.Type is object) @@ -2179,7 +2269,7 @@ namespace System.Linq.Dynamic binaryExpression = Expression.Modulo(finalLeft, finalRight); return (Expression.Lambda>(binaryExpression, parameters)); case ExpressionType.AndAlso: - if (leftIsLambda && rightIsLambda) + if (leftIsLambda && rightIsLambda && sequenceEqual) { return Expression.Equal(left, right); } @@ -2188,7 +2278,7 @@ namespace System.Linq.Dynamic return (Expression.Lambda>(Expression.AndAlso(finalLeft, finalRight), parameters)); } case ExpressionType.OrElse: - if (leftIsLambda && rightIsLambda) + if (leftIsLambda && rightIsLambda && sequenceEqual) { return Expression.Equal(left, right); }