Work on DynamicQueryable to support .Where("shouldBeVisible && Level < 4") rather than .Where("shouldBeVisible == true && Level < 4")

Confirmed other test cases of .Where still work
This commit is contained in:
agrath@gmail.com
2011-02-25 12:16:03 -13:00
parent 3961787463
commit b1ff0db8fe

View File

@@ -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<DynamicNode,object> && Func<DynamicNode,bool>
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<DynamicNode>(right as Expression<Func<DynamicNode, bool>>, Expression.Lambda<Func<DynamicNode, bool>>(unboxedLeft, parameters) as Expression<Func<DynamicNode, bool>>);
}
if (expressionType == ExpressionType.OrElse)
{
return PredicateBuilder.And<DynamicNode>(right as Expression<Func<DynamicNode, bool>>, Expression.Lambda<Func<DynamicNode, bool>>(unboxedLeft, parameters) as Expression<Func<DynamicNode, bool>>);
}
}
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<DynamicNode>(left as Expression<Func<DynamicNode, bool>>, Expression.Lambda<Func<DynamicNode, bool>>(unboxedRight, parameters) as Expression<Func<DynamicNode, bool>>);
}
if (expressionType == ExpressionType.OrElse)
{
return PredicateBuilder.And<DynamicNode>(left as Expression<Func<DynamicNode, bool>>, Expression.Lambda<Func<DynamicNode, bool>>(unboxedRight, parameters) as Expression<Func<DynamicNode, bool>>);
}
}
////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<DynamicNode>(left as Expression<Func<DynamicNode, bool>>, right as Expression<Func<DynamicNode, bool>>);
//}
//if (expressionType == ExpressionType.OrElse)
//{
// return PredicateBuilder.Or<DynamicNode>(left as Expression<Func<DynamicNode, bool>>, right as Expression<Func<DynamicNode, bool>>);
//}
}
}
}
}
}
}
@@ -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<Func<DynamicNode, int>>(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<Func<DynamicNode, DynamicNode, Boolean>>(Expression.AndAlso(finalLeft, finalRight), parameters));
}
case ExpressionType.OrElse:
if (leftIsLambda && rightIsLambda)
if (leftIsLambda && rightIsLambda && sequenceEqual)
{
return Expression.Equal(left, right);
}