#c# #linq
#c# #linq
Вопрос:
В синтаксисе запроса я могу написать
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 для проприетарной объектной модели, чтобы нам не приходилось создавать графический интерфейс для каждого нечетного случая. Было бы полезно, если бы им не нужно было изучать синтаксис запроса. В настоящее время я предоставил фрагменты, решающие эту проблему с помощью foreach , но вопрос все еще возникает время от времени.
Ответ №1:
Это также возможно:
house.rooms.SelectMany(room => room.Doors.Where(door => door.Color == green),
(room, door) => new { r = room, d = door })
Это перегрузка SelectMany
.
Комментарии:
1. Я считаю, что вам нужно переключить параметры door и room во второй строке, чтобы первый параметр был источником, а второй — коллекцией.
(room, door) => new { d=door,r=room })
2. Мне очень нравится
house.rooms.SelectMany(r=>r.Doors,Tuple.Create).Where(t => t.Item2.Color ==green)
. Конечно, вы могли бы поместить этоwhere
предложение в несколько разных мест.3. Это отличный вопрос и отличный ответ. Но, чувак, чтение подписи этого метода в документах msdn немного безумно!
4. @user74754 и добавьте к нему немного выражения: msdn.microsoft.com/nl-nl/library/windows/hardware /…
Ответ №2:
Все запросы LINQ преобразуются компилятором в синтаксис метода (с точками). Нотация запроса — это просто синтаксический сахар.
В спецификации языка C # перевод «из x1 в e1 из x2 в e2» явно вызывается на странице 211.
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
предложения and . На самом деле документация для 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
}
);
Вам просто нужно изменить «владелец» на «комната» и «домашние животные» на «двери» и изменить условие фильтра.
Ответ №3:
Не идеально, но вы всегда можете использовать анонимные типы в SelectMany
: var greendoorsWithRooms = house.rooms.SelectMany(room=> new { Room = room, Doors = room.Doors}) .Where(roomAndDoors=>roomAndDoors.Door.Color==green) .Select(roomAndDoors => ...
Комментарии:
1. Это в значительной степени то, во что компилятор превращает синтаксис запроса под прикрытием. 1