From 6d615e6762d6f2df1bd591dbc2bb321bc4ff0169 Mon Sep 17 00:00:00 2001 From: "agrath@gmail.com" Date: Fri, 25 Feb 2011 16:58:17 -1300 Subject: [PATCH] Work on DynamicQueryable to support .Where("bodyText.Contains(\"string\")") Chaining works too: .Where("Name.SubString(1,3).Contains(\"v\")"); --- .../RazorDynamicNode/DynamicQueryable.cs | 102 ++++++++++++++---- 1 file changed, 83 insertions(+), 19 deletions(-) diff --git a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicQueryable.cs b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicQueryable.cs index cd7920156c..130d5e5069 100644 --- a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicQueryable.cs +++ b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicQueryable.cs @@ -1387,6 +1387,28 @@ namespace System.Linq.Dynamic } Expression[] args = ParseArgumentList(); MethodBase mb; + LambdaExpression instanceAsString = null; + ParameterExpression instanceExpression = Expression.Parameter(typeof(DynamicNode), "instance"); + if (type.IsGenericType) + { + var typeArgs = type.GetGenericArguments(); + if (typeArgs[0] == typeof(DynamicNode)) + { + if (instance != null && instance is LambdaExpression) + { + if (typeArgs[1] == typeof(object)) + { + instanceAsString = StringFormat(instance as LambdaExpression, instanceExpression); + type = typeof(string); + } + if (typeArgs[1] == typeof(string)) + { + instanceAsString = instance as LambdaExpression; + type = typeof(string); + } + } + } + } switch (FindMethod(type, id, instance == null, args, out mb)) { case 0: @@ -1399,6 +1421,47 @@ namespace System.Linq.Dynamic if (method.ReturnType == typeof(void)) throw ParseError(errorPos, Res.MethodIsVoid, id, GetTypeName(method.DeclaringType)); + if (instanceAsString != null) + { + ConstantExpression defaultReturnValue = Expression.Constant(null, typeof(object)); + Type methodReturnType = method.ReturnType; + switch (methodReturnType.Name) + { + case "String": + defaultReturnValue = Expression.Constant(null, typeof(string)); + break; + case "Int32": + defaultReturnValue = Expression.Constant(0, typeof(int)); + break; + case "Boolean": + defaultReturnValue = Expression.Constant(false, typeof(bool)); + break; + } + ParameterExpression result = Expression.Parameter(method.ReturnType, "result"); + LabelTarget blockReturnLabel = Expression.Label(method.ReturnType); + BlockExpression block = Expression.Block( + method.ReturnType, + new[] { result }, + Expression.Assign(result, + Expression.Call( + Expression.Invoke(instanceAsString, instanceExpression), + method, + args) + ), + Expression.Return(blockReturnLabel, result), + Expression.Label(blockReturnLabel, defaultReturnValue) + ); + + switch (methodReturnType.Name) + { + case "String": + return Expression.Lambda>(block, instanceExpression); + case "Int32": + return Expression.Lambda>(block, instanceExpression); + case "Boolean": + return Expression.Lambda>(block, instanceExpression); + } + } return Expression.Call(instance, (MethodInfo)method, args); default: throw ParseError(errorPos, Res.AmbiguousMethodInvocation, @@ -1465,7 +1528,27 @@ namespace System.Linq.Dynamic } return null; } + LambdaExpression StringFormat(LambdaExpression lax, ParameterExpression instanceExpression) + { + ParameterExpression cresult = Expression.Parameter(typeof(string), "cresult"); + ParameterExpression temp = Expression.Parameter(typeof(object), "temp"); + ParameterExpression stemp = Expression.Parameter(typeof(string), "string"); + LabelTarget cblockReturnLabel = Expression.Label(typeof(string)); + MethodInfo stringFormat = typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(object) }); + BlockExpression cblock = Expression.Block( + typeof(string), + new[] { cresult, temp }, + Expression.Assign(temp, Expression.Invoke(lax, instanceExpression)), + Expression.Assign(cresult, Expression.Call(stringFormat, Expression.Constant("{0}"), temp)), + Expression.Return(cblockReturnLabel, cresult), + Expression.Label(cblockReturnLabel, Expression.Constant(null, typeof(string)))); + + LambdaExpression lax2 = Expression.Lambda>(cblock, instanceExpression); + var expression = Expression.Lambda>(cblock, instanceExpression); + return expression; + + } Expression ParseAggregate(Expression instance, Type elementType, string methodName, int errorPos) { ParameterExpression outerIt = it; @@ -2181,25 +2264,6 @@ namespace System.Linq.Dynamic } } - - ////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>); - //} - - } } }