Left Outer Join with Aggregating Group By and Conditional Key Failure
Description
Environment
None
Activity
Show:
Alex Zaytsev May 1, 2017 at 3:42 AM
Closing issues resolved in 4.1.0
Duncan Munro January 28, 2016 at 11:20 PM
Duncan Munro January 28, 2016 at 10:29 PM
After a little more testing, I've found that if the query has at least one outer join in it then it works as expected.
Duncan Munro January 28, 2016 at 8:52 PM
I'm sure I'm the only person this bug affects, but it is causing stuff to not work in my design.
I either need to flatten array indexes earlier, or the groupby key nominator needs to ignore the wrapping/unwrapping of objects.
Fixed
Details
Details
Assignee
Unassigned
UnassignedReporter
Duncan Munro
Duncan MunroLabels
Components
Fix versions
Affects versions
Priority
Who's Looking?
Open Who's Looking?
Created January 28, 2016 at 8:50 PM
Updated May 1, 2017 at 3:42 AM
Resolved June 9, 2016 at 9:42 PM
Who's Looking?
Once again, I have a weirdly specific use case that tries to combine joining, grouping, and conditionals. Actually, it's the same issue that I thought I had solved almost half a year ago with NH-3800: Cannot combine Left Outer Join with Aggregating Group ByClosed and NH-3801.
The previous fixes are working well, but I found a corner case the breaks down.
The code I'm running is generating a LINQ query programmatically that first tries to resolve a number of outer joins. To do this, I wrap my initial entity in an object array. Then as I'm building the group by clauses I extract the required entity (or entities) from the object array and build by group by key as an object array.
So (at minimum) you get something like this
var query = baseQuery.Select(x => new object[] { x }).GroupBy(array => new object[] { ((Entity)array[0]).Prop == value ? "A" : "B" }).Select(g => new { Key = g.Key, Count = g.Count());
Only more complicated....
Anyway, the whole thing fails because the group key nomination happens before the array flattening.
The group by expression essentially looks like
new object[] { ((Entity)(new object[] { x }[0])).Prop == value ? "A" : "B" }
And this gets translated to
new object[] { ((Entity)(<nominated>[0])).Prop == value ? "A" : "B" }
When what needs to happen is
new object[] { <nominated> }