在Linq中使用点分子语法时,我可以访问SelectMany的跳过的"父"吗?

Tor*_*mod 19 c# linq

在查询语法中我可以写

var greendoorsWithRooms = from room in house.roooms
from door in room.doors
where door.Color = green
select new {d=door,r=room}
Run Code Online (Sandbox Code Playgroud)

有没有办法用虚线语法实现同样的目的?

var greendoorsWithRooms = house.rooms.SelectMany(room=>room.Doors)
     .Where(door=>door.Color==green)
     .Select(door=>new{ <room is not in scope> }
Run Code Online (Sandbox Code Playgroud)

我正在教一些非程序员使用LINQPad来对照专有对象模型,这样我们就不必围绕每个奇怪的情况创建GUI.如果他们不必学习查询语法将是有益的.目前,我已经提供了使用foreach解决这个问题的片段,但问题仍然偶尔会出现.

Ger*_*old 43

这也是可能的:

house.rooms.SelectMany(room => room.Doors.Where(door => door.Color == green),
   (room, door) => new { r = room, d = door })
Run Code Online (Sandbox Code Playgroud)

这是这个过载SelectMany.

  • 我相信您需要在第二行切换门和房间参数,以便第一个参数是源,第二个参数是集合.`(房间,门)=>新{d =门,r =房间})` (2认同)
  • 我非常喜欢`house.rooms.SelectMany(r=&gt;r.Doors,Tuple.Create).Where(t =&gt; t.Item2.Color ==green)`。当然,您可以将“where”子句放在几个不同的位置。 (2认同)
  • 这是一个很好的问题,也是一个很好的答案。但是,伙计,在msdn docs中读取该方法的签名有点疯狂! (2认同)

Ray*_*hen 9

所有LINQ查询都由编译器转换为点分表示法.流利的符号只是语法糖.

C#语言规范中,在第211页上明确地调出了"从e1中的x1到e2中的x2"的转换.

from x1 in e1 from x2 in e2
Run Code Online (Sandbox Code Playgroud)

from * in (e1).SelectMany(x1 => e2, (x1, x2) => new { x1, x2 })
Run Code Online (Sandbox Code Playgroud)

然后按照食谱,你的例子就是

from * in house.rooms.SelectMany(room => room.doors, (room, doors) => new { room, doors })
Run Code Online (Sandbox Code Playgroud)

然后你将通过添加WhereSelect子句完成转换为点分表示法.事实上,文档提供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
            }
    );
Run Code Online (Sandbox Code Playgroud)

您只需将"所有者"更改为"房间",将"宠物"更改为"门"并更改过滤条件.