Can I access the skipped "parent" of SelectMany when using dotted syntax in Linq?
In query syntax I can write
var greendoorsWithRooms = from room in house.roooms
from door in room.doors
where door.Color = green
select new {d=开发者_高级运维door,r=room}
Is there a way I could achieve the same with dotted syntax?
var greendoorsWithRooms = house.rooms.SelectMany(room=>room.Doors)
.Where(door=>door.Color==green)
.Select(door=>new{ <room is not in scope> }
I am teaching some non-programmers to use LINQPad against a proprietary object model so that we don't have to create GUI around every odd case. It would be beneficial if they didn't have to learn query syntax. Presently, I've supplied snippets solving this using foreach, but the question still comes up once in a while.
This is also possible:
house.rooms.SelectMany(room => room.Doors.Where(door => door.Color == green),
(room, door) => new { r = room, d = door })
It's this overload of SelectMany
.
All LINQ queries are converted by the compiler into method (dotted) syntax. Query notation is just syntactic sugar.
In the C# language specification, the translation of "from x1 in e1 from x2 in e2" is explicitly called out on page 211.
from x1 in e1 from x2 in e2
becomes
from * in (e1).SelectMany(x1 => e2, (x1, x2) => new { x1, x2 })
Following the cookbook then, your example would be
from * in house.rooms.SelectMany(room => room.doors, (room, doors) => new { room, doors })
and then you would complete the conversion to dotted notation by adding Where
and Select
clauses. In fact the documentation for SelectMany
gives your query as an example!
var query =
petOwners
.SelectMany(petOwner => petOwner.Pets,
(petOwner, petName) => new { petOwner, petName })
.Where(ownerAndPet => ownerAndPet.petName.StartsWith("S"))
.Select(ownerAndPet =>
new
{
Owner = ownerAndPet.petOwner.Name,
Pet = ownerAndPet.petName
}
);
You just have to change "owner" to "room" and "pets" to "doors" and change your filter condition.
Not ideal, but you could always use anonymous types in SelectMany
:
var greendoorsWithRooms = house.rooms.SelectMany(room=> new { Room = room, Doors = room.Doors}) .Where(roomAndDoors=>roomAndDoors.Door.Color==green) .Select(roomAndDoors => ...
精彩评论