LINQ - SelectMany OrderBy Outer Value and then Inner Value
c#, linq, linqpad
Solution
Yes, there is a difference. Your query returns incorrect results. Check your query results for following input array:
var fullNames = new[] { "Anne Williams", "Sue Green", "John Fred Smith" }
.AsQueryable();
Sample query results:
Anne came from Anne Williams
Williams came from Anne Williams
Fred came from John Fred Smith
John came from John Fred Smith
Smith came from John Fred Smith
Green came from Sue Green
Sue came from Sue Green
Your query results:
Anne came from Anne Williams
Williams came from Anne Williams
Green came from Sue Green
Sue came from Sue Green
Fred came from John Fred Smith
John came from John Fred Smith
Smith came from John Fred Smith
Problem is you're ordering for every item in source array separately, so you're items are in exactly the same order as in input array. The sample query orders all items after they are generated.
Your query works in following way:
Element from input array is taken. The first one would be `"Anne Williams"`. End query if no more elements.
It's split into parts, so we get: `["Anne", "Williams"]`.
Sort is applied on current input element `"Anne Williams"` and split parts `["Anne", "Williams"]`.
Sorted elements are returned one after another: `"Anne came from Anne Williams"` and `"Williamscame from Anne Williams"`.
It moves back to point 1.
And sample query works that way:
Element from input array is taken. The first one would be `"Anne Williams"`. If no more elements go to 5.
It's split into parts, so we get: `["Anne", "Williams"]`.
elements are returned one after another: `"Anne came from Anne Williams"` and `"Williamscame from Anne Williams"`.
It moves back to point 1.
Sort is applied on all selected elements.
Problem
I've been going through the Linqpad sample linq examples. Under "Projecting - SelectMany" they ask you to try and Translat the following linq syntax to Fluent Syntax. This is there sample: ``` var fullNames = new[] { "Anne Williams", "John Fred Smith", "Sue Green" } .AsQueryable(); IEnumerable<string> query = from fullName in fullNames from name in fullName.Split() orderby fullName, name select name + " came from " + fullName; query.Dump(); ``` I converted it using the following: ``` var myQuery = fullNames .SelectMany( fullName => fullName.Split() .OrderBy(fn => fullName) .ThenBy(fn=> fn) , (fullName, name) => ((name + " came from ") + fullName) ); ``` However linqpad generates the following: ``` IEnumerable<string> query2 = fullNames .SelectMany (fName => fName.Split().Select (name => new { name, fName } )) .OrderBy (x => x.fName) .ThenBy (x => x.name) .Select (x => x.name + " came from " + x.fName); ``` Both return the same results. Is one faster then the other? Which one do you think looks better? Thoughts?