Hi Fabian.
Thanks so much for the explanation. I'll try working with this
knowledge as soon as I get a chance.
Patrick Earl
On Tue, Feb 15, 2011 at 1:07 AM, Fabian Schmied
<[email protected]> wrote:
>> I am seeing another strange problem. I have an expression that looks like:
>>
>> (sb, name) => sb.Length > 0 ? sb.Append(", ").Append(name) : sb.Append(name)
>>
>> Unfortunately, by the time it gets to the AggregateBySeed, the
>> expression looks something like:
>>
>> sb => sb.Length > 0 ? sb.Append(", ").Append([100001].name) :
>> sb.Append([100001].name))
>>
>> I haven't had time to analyze why "name" was eaten, but I wonder if
>> the new operators have an undetected relinq bug.
>
> The "[100001]" expression is a reference to the query source whose
> "name" property is aggregated. (If you use the
> FormattingExpressionTreeVisitor.Format method instead of
> Expression.ToString(), you'll see a more sensible expression.)
>
> Here's an example:
>
> (from o in Orders select o.Name).Aggregate (new StringBuilder(), (sb,
> name) => sb.Length > 0 ? sb.Append(", ").Append(name) :
> sb.Append(name))
>
> This becomes the following QueryModel:
>
> MainFromClause: from o in Orders
> SelectClause: select [o].Name
> AggregateFromSeedResultOperator:
> Seed = new StringBuilder()
> Func = sb => sb.Length > 0 ? sb.Append(", ").Append([o].name) :
> sb.Append([o].name)
>
> ("[o]" denotes a reference to the query source "o", ie., a
> QuerySourceReferenceExpression pointing to the MainFromClause.)
>
> This is what re-linq always does when analyzing query operator
> methods: it deduces what the input of the query operator actually
> constitutes, and then puts a "resolved" expression into the result
> operator.
>
> In a LINQ provider, you usually have a mapping from IQuerySource
> instances (eg., the MainFromClause) to something that describes the
> data source in your target query system. In your case, this would
> probably be the HQL AST node that represents the respective HQL "from"
> clause. I'm quite sure that you already have that mapping because you
> also need it to, eg., translate the QueryModel's "select" expression.
> Use it to translate the result operator's Func to HQL.
>
> If, for some reason, you cannot use that mapping, you can
> reverse-resolve the expression. Check out the source code of
> ExecuteInMemory[1] or contact me at
> "http://groups.google.com/group/re-motion-users" if you need info on
> how to do this.
>
> Fabian
>
> [1]
> "https://svn.re-motion.org/svn/Remotion/trunk/Remotion/Data/Linq/Clauses/ResultOperators/AggregateFromSeedResultOperator.cs"
>
>> On Tue, Feb 8, 2011 at 4:16 AM, Fabian Schmied <[email protected]>
>> wrote:
>>> This is a guess without seeing any of the exceptions:
>>>
>>> You (ie., some committer to NH) probably worked around a missing expression
>>> parser for Queryable.Aggregate in a previous version of re-linq by handling
>>> the respective MethodCallExpressions in an expression visitor. In the
>>> current version, re-linq now recognizes the Aggregate methods as query
>>> operators and converts them into
>>> AggregateResultOperator/AggregateFromSeedResultOperator instances (similar
>>> to what it does for all query operators).
>>>
>>> This means the code previously handling the MethodCallExpressions for
>>> Queryable.Aggregate should now be rewritten to handle the result operators
>>> instead.
>>>
>>> In general, whenever you have a query operator that's not detected by
>>> re-linq, please don't write code handling the MethodCallExpressions
>>> directly, but instead add an expression parser (IExpressionNode
>>> implementation) for that method. This approach has several advantages, among
>>> others that you avoid breaking your code with later versions of re-linq. See
>>> my blog post
>>> (https://www.re-motion.org/blogs/mix/archive/2010/10/28/re-linq-extensibility-custom-query-operators.aspx),
>>> and post to the re-motion-users mailing list if there are any
>>> questions/problems (or if re-linq is missing a standard query operator).
>>>
>>> (Out of curiosity: If I'm guessing correctly, _how_ do you actually
>>> translate the Aggregate query operator to HQL? After all, the aggregation
>>> function could contain completely arbitrary code...)
>>>
>>> Regards,
>>> Fabian
>>
>