tag:blogger.com,1999:blog-4155628149386914837.post848768152102581929..comments2024-01-01T20:54:44.562+07:00Comments on KristoferA's blog: Code sample: Search and replace in Linq expression treesKristoferAhttp://www.blogger.com/profile/01779909152712388764noreply@blogger.comBlogger12125tag:blogger.com,1999:blog-4155628149386914837.post-92233625889531547842010-08-26T12:24:08.655+07:002010-08-26T12:24:08.655+07:00How to implement what for InvocationExpression? Th...How to implement what for InvocationExpression? The replace thing? You can use the parameterexpression sample to do the same thing with invocationexpression. Or even tweak it to a more generic search-and-replace for any kind of expression. The only reason I made it for just parameterexpression is that I only needed to replace parameterexpressions at the time...KristoferAhttps://www.blogger.com/profile/01779909152712388764noreply@blogger.comtag:blogger.com,1999:blog-4155628149386914837.post-39646808907680625412010-08-26T03:52:11.294+07:002010-08-26T03:52:11.294+07:00Thanks for the tip! It was interesting reading, bu...Thanks for the tip! It was interesting reading, but I think I have to read it a few time to get it completely :)<br /><br />Any idea how to implement it for an InvocationExpression?Kshanhttps://www.blogger.com/profile/15690663650532456357noreply@blogger.comtag:blogger.com,1999:blog-4155628149386914837.post-74253388706439780502010-08-25T16:00:46.483+07:002010-08-25T16:00:46.483+07:00@Kshan,
Ok. Depending on what you're trying t...@Kshan,<br /><br />Ok. Depending on what you're trying to do, IQueryable wrappers may come in handy too...<br /><br />Check out this article in Alex James' blog:<br />http://blogs.msdn.com/b/alexj/archive/2010/03/01/tip-55-how-to-extend-an-iqueryable-by-wrapping-it.aspxKristoferAhttps://www.blogger.com/profile/01779909152712388764noreply@blogger.comtag:blogger.com,1999:blog-4155628149386914837.post-62438384127373877202010-08-25T11:36:02.376+07:002010-08-25T11:36:02.376+07:00Ah, I see. Thank you.
I am trying to convert an e...Ah, I see. Thank you.<br /><br />I am trying to convert an expression tree from one that is used in the repository pattern to one that can be used against an ObjectContext. I am doing this for compiled queries. So far, it has been extremely painful.<br /><br />Thank you for this bit of code!Kshanhttps://www.blogger.com/profile/15690663650532456357noreply@blogger.comtag:blogger.com,1999:blog-4155628149386914837.post-85573406305397220882010-08-25T10:07:25.712+07:002010-08-25T10:07:25.712+07:00Argh, looks like blogger/blogspot cleaned out a de...Argh, looks like blogger/blogspot cleaned out a decent portion of the sample in the previous comment. Trying again:<br /><br />Expression < Func < T, T > > someExpression = ...;<br />ParameterExpression oldParam = (ParameterExpression)((LambdaExpression)someExpression).Parameters[0];<br />ParameterExpression newParam = Expression.Parameter(T, "");<br />Expression < Func < T, T > > newExp = someExpression.ReplaceParameter(oldParam, newParam);KristoferAhttps://www.blogger.com/profile/01779909152712388764noreply@blogger.comtag:blogger.com,1999:blog-4155628149386914837.post-72756894509978096352010-08-25T10:05:05.098+07:002010-08-25T10:05:05.098+07:00@Kshan,
It will evaluate to false if you pass an ...@Kshan,<br /><br />It will evaluate to false if you pass an identical parameterexpression instead of a reference to the exact parameterexpression that you want to replace.<br /><br />You must pass a reference to the parameter from your expression, e.g.:<br /><br />Expression> someExpression = ...;<br />ParameterExpression oldParam = (ParameterExpression)((LambdaExpression)someExpression).Parameters[0];<br />ParameterExpression newParam = Expression.Parameter(T, "");<br />Expression> newExp = someExpression.ReplaceParameter(oldParam, newParam);KristoferAhttps://www.blogger.com/profile/01779909152712388764noreply@blogger.comtag:blogger.com,1999:blog-4155628149386914837.post-3308732030142956852010-08-25T08:02:00.617+07:002010-08-25T08:02:00.617+07:00It appears that
if (expression.Equals(oldParamet...It appears that <br /><br />if (expression.Equals(oldParameter)) <br /><br />in "public static ParameterExpression ReplaceParameter..."<br /><br />always evaluates to false (even if everything matches up) and hence the parameters do not get switched out. How did you get this to work?<br /><br />Here is the little example I tested with that fails:<br /> ParameterExpression p1 = Expression.Parameter(typeof(int), "i");<br /> ParameterExpression p2 = Expression.Parameter(typeof(int), "d");<br /><br /> Expression> exp = i => i + 5;<br /><br />It also seems to fail for more complex expressions such as:<br /> Expression> expr = ctx => ctx.DBTableObject.Where(x => x.Name == "FirstName").Single();<br /><br /><br />Any ideas?Kshanhttps://www.blogger.com/profile/15690663650532456357noreply@blogger.comtag:blogger.com,1999:blog-4155628149386914837.post-27251678966567440032010-08-20T10:10:54.573+07:002010-08-20T10:10:54.573+07:00@Anonymous,
Yes, the original didn't cover in...@Anonymous,<br /><br />Yes, the original didn't cover inherited expressions. You can even simplify it a bit with:<br /><br />"expressionType is ParameterExpression" <br /><br />...instead of:<br /><br />"expressionType == typeof(ParameterExpression) || expressionType.IsSubclassOf(typeof(ParameterExpression))"<br /><br />...etc...KristoferAhttps://www.blogger.com/profile/01779909152712388764noreply@blogger.comtag:blogger.com,1999:blog-4155628149386914837.post-58347667912300659792010-08-20T06:37:26.090+07:002010-08-20T06:37:26.090+07:00Thanks a bunch! I've ended up with the main me...Thanks a bunch! I've ended up with the main method as following:<br /><br />public static Expression ReplaceParameter(this Expression expression, ParameterExpression oldParameter, ParameterExpression newParameter)<br />{<br /> Expression exp = null;<br /> Type expressionType = expression.GetType();<br /> if (expressionType == typeof(ParameterExpression) || expressionType.IsSubclassOf(typeof(ParameterExpression)))<br /> {<br /> exp = ((ParameterExpression)expression).ReplaceParameter(oldParameter, newParameter);<br /> }<br /> else if (expressionType == typeof(MemberExpression) || expressionType.IsSubclassOf(typeof(MemberExpression)))<br /> {<br /> exp = ((MemberExpression)expression).ReplaceParameter(oldParameter, newParameter);<br /> }<br /> else if (expressionType == typeof(MethodCallExpression) || expressionType.IsSubclassOf(typeof(MethodCallExpression)))<br /> {<br /> exp = ((MethodCallExpression)expression).ReplaceParameter(oldParameter, newParameter);<br /> }<br /> else if (expressionType == typeof(NewExpression) || expressionType.IsSubclassOf(typeof(NewExpression)))<br /> {<br /> exp = ((NewExpression)expression).ReplaceParameter(oldParameter, newParameter);<br /> }<br /> else if (expressionType == typeof(UnaryExpression) || expressionType.IsSubclassOf(typeof(UnaryExpression)))<br /> {<br /> exp = ((UnaryExpression)expression).ReplaceParameter(oldParameter, newParameter);<br /> }<br /> else if (expressionType == typeof(ConstantExpression) || expressionType.IsSubclassOf(typeof(ConstantExpression)))<br /> {<br /> exp = ((ConstantExpression)expression).ReplaceParameter(oldParameter, newParameter);<br /> }<br /> else if (expressionType == typeof(ConditionalExpression) || expressionType.IsSubclassOf(typeof(ConditionalExpression)))<br /> {<br /> exp = ((ConditionalExpression)expression).ReplaceParameter(oldParameter, newParameter);<br /> }<br /> else if (expressionType == typeof(LambdaExpression) || expressionType.IsSubclassOf(typeof(LambdaExpression)))<br /> {<br /> exp = ((LambdaExpression)expression).ReplaceParameter(oldParameter, newParameter);<br /> }<br /> else if (expressionType == typeof(MemberInitExpression) || expressionType.IsSubclassOf(typeof(MemberInitExpression)))<br /> {<br /> exp = ((MemberInitExpression)expression).ReplaceParameter(oldParameter, newParameter);<br /> }<br /> else if (expressionType == typeof(BinaryExpression) || expressionType.IsSubclassOf(typeof(BinaryExpression)))<br /> {<br /> exp = ((BinaryExpression)expression).ReplaceParameter(oldParameter, newParameter);<br /> }<br /> else if (expressionType == typeof(ConstantExpression) || expressionType.IsSubclassOf(typeof(ConstantExpression)))<br /> {<br /> exp = expression;<br /> }<br /> else<br /> {<br /> //did I forget some expression type? probably. this will take care of that... :)<br /> throw new NotImplementedException("Expression type " + expression.GetType().FullName + " not supported by this expression tree parser.");<br /> }<br /> return exp;<br />}Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-4155628149386914837.post-89359087956440948182009-11-30T14:03:31.471+07:002009-11-30T14:03:31.471+07:00Ah, I knew I forgot something. :)Ah, I knew I forgot something. :)KristoferAhttps://www.blogger.com/profile/01779909152712388764noreply@blogger.comtag:blogger.com,1999:blog-4155628149386914837.post-73323180271668305552009-11-19T22:57:21.889+07:002009-11-19T22:57:21.889+07:00Well, after implementing InvocationExpression (or ...Well, after implementing InvocationExpression (or trying) this seems to work nicely.<br />I can send you the cs mod if you want - let me know: theo =a=t= beisch.deAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-4155628149386914837.post-33019472925765054942009-11-19T04:23:00.133+07:002009-11-19T04:23:00.133+07:00Thanks, great help. Just stumbled across one missi...Thanks, great help. Just stumbled across one missing: InvocationExpression.<br />Can you post some sample?<br />Best regards - sorry for the anonymous post - you can reach me under theo _a_t_ beisch.deAnonymousnoreply@blogger.com