在查询语法中我可以写
var greendoorsWithRooms = from room in house.roooms
from door in room.doors
where door.Color = green
select new {d=door,r=room}
有没有办法用虚线语法实现相同的效果?
var greendoorsWithRooms = house.rooms.SelectMany(room=>room.Doors)
.Where(door=>door.Color==green)
.Select(door=>new{ <room is not in scope> }
我正在教一些非程序员使用LINQPad来对照专有对象模型,这样我们就不必围绕每个奇怪的情况创建GUI。如果他们不必学习查询语法将是有益的。目前,我已经提供了使用foreach解决此问题的片段,但问题仍然偶尔会出现。
答案 0 :(得分:38)
这也是可能的:
house.rooms.SelectMany(room => room.Doors.Where(door => door.Color == green),
(room, door) => new { r = room, d = door })
SelectMany
的{{3}}超载。
答案 1 :(得分:9)
所有LINQ查询都由编译器转换为点分表示法。流利的符号只是语法糖。
在C# language specification中,在第211页明确地调出了“从e1中的x1到e2中的x2”的翻译。
from x1 in e1 from x2 in e2
变为
from * in (e1).SelectMany(x1 => e2, (x1, x2) => new { x1, x2 })
然后按照食谱,你的例子将是
from * in house.rooms.SelectMany(room => room.doors, (room, doors) => new { room, doors })
然后您将通过添加Where
和Select
子句完成转换为点分表示法。事实上,the documentation for SelectMany
以您的查询为例!
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
}
);
您只需将“所有者”更改为“房间”,将“宠物”更改为“门”并更改过滤条件。
答案 2 :(得分:2)
不理想,但您可以始终在SelectMany
中使用匿名类型:
var greendoorsWithRooms = house.rooms.SelectMany(room=> new { Room = room, Doors = room.Doors}) .Where(roomAndDoors=>roomAndDoors.Door.Color==green) .Select(roomAndDoors => ...