items.Where(item => item.ChildrenProperty.Any())
items.Where(item => item.ChildrenExtensionMethod().Any())
Remotion.Linq.Parsing.ParserException : Cannot parse expression 'item' as it has an unsupported type. Only query sources (that is, expressions that implement IEnumerable) and query operators can be parsed.----> Remotion.Linq.Utilities.ArgumentTypeException : Expected a type implementing IEnumerable<T>, but found 'Umbraco.Cms.Web.Model.Content'.Parameter name: expression
I'll have to dig into the code before I can make a qualified statement
about this issue.
I should be able to take some time to investigate it tomorrow.
Cheers,
Fabian
[...]
> items.Where(item => item.ChildrenExtensionMethod().Any())
>
> However, that latter query throws an exception when being parsed by Relinq -
> because GetQueryOperatorExpression in Relinq's default ExpressionTreeParser
> always returns method call expressions unmodified whereas members that
> aren't operators are treated differently, so when it hits my method the
> parser continues up the expression tree in the subquery until it gets to
> "item" and I get the following error:
[...]
Yes, you're right. re-linq currently assumes that all methods
occurring in a query operator call chain should be treated like query
operators (Where, Select, etc.). In your case this means that re-linq
regards "item" as the start of the query operator chain and, since
item doesn't implement IEnumerable<T>, throws an exception. Even if
item implemented IEnumerable<T>, an exception would be thrown that
ChildrenExtensionMethod() "is currently not supported", unless you've
registered a custom node parser for that method.
To support this out of the box, re-linq's query operator detection
semantics would have to be changed somehow. I'll discuss this in a
separate thread (and/or blog post).
Now, back to your scenario. Yes, you can tweak re-linq to support this
without implementing a custom ExpressionTreeParser. You just need to
replace the method call with a different expression before the
ExpressionTreeParser tries to parse it. The easiest way to do so is to
implement a light-weight expression transformer (implementing
IExpressionTransformer<MethodCallExpression>) that you register when
you create your QueryParser. See here for an explanation on how to do
that: "https://www.re-motion.org/blogs/mix/2011/04/29/re-linq-customizability-explained/".
The transformer should detect calls to "ChildrenExtensionMethod()" and
replace those with a different expression. I'd probably define a
custom expression type derived from ExtensionExpression for this
("RelationAccessExpression" or something like that).
Gordon: You wrote you were surprised that Alex didn't need to
implement his own ExpressionTreeParser, since you were using several.
I think you meant Expression _visitors_, right? Of these I guess Alex
also has a few :)
Regards,
Fabian
Cheers,
Gordon.
-----Original Message-----
From: Fabian Schmied
Sent: Tuesday, December 20, 2011 2:41 AM
To: re-moti...@googlegroups.com
Subject: Re: [re-motion-users] Is it possible to use a custom extension
method in a subquery with OOB ExpressionTreeParser?
Hi again,
[...]
[...]
Regards,
Fabian
--
Here's the blog post: "https://www.re-motion.org/blogs/mix/2011/12/20/
re-linq-how-to-recognize-if-a-method-is-a-query-operator/", and here's
the discussion: "http://groups.google.com/group/re-motion-dev/
browse_thread/thread/f9f6198bbbecd796".
I'd be very interested in hearing your opinions as LINQ provider
implementers.
Fabian