new Transport("самолет", "Воздушный"),
new Transport("каноэ", "Речной"),
new Transport("биплан", "Воздушный"),
new Transport("автомашина", "Наземный"),
new Transport("судно", "Морской"),
new Transport("поезд", "Наземный")
};
// Сформировать запрос, в котором групповое
// объединение используется для составления списка
// видов транспорта по соответствующим категориям,
var byHow = from how in travelTypes
join trans in transports
on how equals trans.How
into lst
select new { How = how, Tlist = lst };
// Выполнить запрос и вывести его результаты,
foreach(var t in byHow) {
Console.WriteLine("К категории <{0} транспорт> относится:", t.How);
foreach(var m in t.Tlist)
Console.WriteLine(" " + m.Name);
Console.WriteLine();
}
}
}
Ниже приведен результат выполнения этой программы.
К категории <Воздушный транспорт> относится:
аэростат
самолет
биплан
К категории <Морской транспорт> относится:
судно
К категории <Наземный транспорт> относится:
велосипед
автомашина
поезд
К категории <Речной транспорт>
относится:
лодка
каноэ
Главной частью данной программы, безусловно, является следующий запрос.
var byHow = from how in travelTypes
join trans in transports
on how equals trans.How
into 1st
select new { How = how, Tlist = 1st };
Этот запрос формируется следующим образом. В операторе from
используется переменная диапазона how
для охвата всего массива travelTypes
. Напомним, что массив travelTypes
содержит названия общих категорий транспорта: воздушного, наземного, морского и речного. Каждый вид транспорта объединяется в операторе join
со своей категорией. Например, велосипед, автомашина и поезд объединяются с наземным транспортом. Но благодаря оператору into
для каждой категории транспорта в операторе join
составляется список видов транспорта, относящихся к данной категории. Этот список сохраняется в переменной lst
. И наконец, оператор select
возвращает объект анонимного типа, инкапсулирующий каждое значение переменной how
(категории транспорта) вместе со списком видов транспорта. Именно поэтому для вывода результатов запроса требуются два цикла foreach
.
foreach(var t in byHow) {
Console.WriteLine("К категории <{0} транспорт> относится:", t.How);
foreach(var m in t.Tlist)
Console.WriteLine(" " + m.Name);
Console.WriteLine();
}
Во внешнем цикле получается объект, содержащий наименование общей категории транспорта, и список видов транспорта, относящихся к этой категории. А во внутреннем цикле выводятся отдельные виды транспорта.
Методы запроса
Синтаксис запроса, описанный в предыдущих разделах, применяется при формировании большинства запросов в С#. Он удобен, эффективен и компактен, хотя и не является единственным способом формирования запросов. Другой способ состоит в использовании
Методы запроса определяются в классе System.Linq.Enumerable
и реализуются в IEnumerable
. (Методы запроса определяются также в классе System.Linq.Queryable
, расширяющем функции обобщенной формы интерфейса IQueryable
, но этот интерфейс в настоящей главе не рассматривается.) Метод расширения дополняет функции IEnumerable
.