Книга: C# 4.0: полное руководство

Создание группового объединения

Создание группового объединения

Как пояснялось ранее, оператор into можно использовать вместе с оператором join для создания группового объединения, образующего последовательность, в которой каждый результат состоит из элементов данных из первой последовательности и группы всех совпадающих элементов из второй последовательности. Примеры группового объединения не приводились выше потому, что в этом объединении нередко применяется анонимный тип. Но теперь, когда представлены анонимные типы, можно обратиться к простому примеру группового объединения.

В приведенном ниже примере программы групповое объединение используется для составления списка, в котором различные транспортные средства (автомашины, суда и самолеты) организованы по общим для них категориям транспорта: наземного, морского, воздушного и речного. В этой программе сначала создается класс Transport, связывающий вид транспорта с его классификацией. Затем в методе Main() формируются две входные последовательности. Первая из них представляет собой массив символьных строк, содержащих названия общих категорий транспорта: наземного, морского, воздушного и речного, а вторая — массив объектов типа Transport, инкапсулирующих различные транспортные средства. Полученное в итоге групповое объединение используется для составления списка транспортных средств, организованных по соответствующим категориям.

// Продемонстрировать применение простого группового объединения.
using System;
using System.Linq;
// Этот класс связывает наименование вида транспорта,
// например поезда, с общей классификацией транспорта:
// наземного, морского, воздушного или речного,
class Transport {
  public string Name { get; set; }
  public string How { get; set; }
  public Transport(string n, string h) {
    Name = n;
    How = h;
  }
}
class GroupJoinDemo {
  static void Main() {
    // Массив классификации видов транспорта,
    string[] travelTypes = {
      "Воздушный",
      "Морской",
      "Наземный",
      "Речной",
    };
    // Массив видов транспорта.
    Transport[] transports = {
      new Transport("велосипед", "Наземный"),
      new Transport ("аэростат", "Воздушный"),
      new Transport("лодка", "Речной"),
      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();
}

Во внешнем цикле получается объект, содержащий наименование общей категории транспорта, и список видов транспорта, относящихся к этой категории. А во внутреннем цикле выводятся отдельные виды транспорта.

Оглавление книги


Генерация: 1.518. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз