Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Использование технологии LINQ↑ Стр 1 из 8Следующая ⇒ Содержание книги
Похожие статьи вашей тематики
Поиск на нашем сайте
Лабораторная работа № 18
Использование технологии LINQ для работы с данными
Время выполнения работы – 4 часа
Цель работы Ознакомление с технологией LINO и ее использованием для работы с данными. Техническое обеспечение 2.1 Персональная ЭВМ IBM Pentium III и более поздних моделей c оперативной памятью не менее 512 Мбайт. 2.2 Клавиатура. 2.3 Дисплей. 2.4 Манипулятор типа “мышь”. Программное обеспечение 3.1 Операционная система Windows XP SP 3 более поздние версии Windows. 3.2 Система программирования Microsoft Visual Studio 2005 и более поздние версии. Постановка задачи Разработать Windows-приложения согласно варианта задания, которые приведены в разделе 6, используя табличный ввод и вывод данных.
Использование технологии LINQ Технология LINQ (Language Integrated Query) предназначена для обработки (запросов и преобразований) практически любого типа источника данных, начиная от массивов, файлов, строк, коллекций объектов.NET Framework, баз данных SQL Server, наборов данных ADO.NET (DataSet) и XML-документов. LINQ упрощает ситуацию, предлагая единообразные стандартные шаблоны для работы с данными в различных видах источников и форматов данных. Стандартные шаблоны включают в себя основные операции запросов LINQ: фильтрация, упорядочение, группировка, соединение, выбор (проецирование), статистическая обработка. По форме синтаксис языка LINQ очень похож на язык запросов SQL. В данной главе рассмотрим типичные LINQ-запросы и преобразования к некоторым источникам данных. LINQ-запрос к массиву данных LINQ-запрос представляет собой выражение, извлекающее данные из источника данных. Все операции запроса LINQ состоят из трех различных действий: получение источника (в нашем случае — это присвоение Начальных значений исходному массиву) данных, создание запроса (начинается с предложения from) и непосредственное выполнение запроса (обычно это цикл foreach). В данном разделе рассмотрим две задачи, первая — из массива имен извлекаем имена длиной шесть символов, записывая их или в список (коллекцию), или в новый массив. Другая -задача— из массива целых чисел выбираем только те, значения которых больше четырех, также записывая результат запроса в список или массив. Итак, запустим Visual Studio 2010, закажем новый проект шаблона Windows Forms Application С#. Затем из панели элементов перенесем в форму текстовое поле. Далее через щелчок правой кнопкой мыши перейдем к вкладке программного кода (листинг 19.1). Листинг 19.1. Извлечение данных из массивов // Решаем две задачи по выбору элементов из массива с помощью стандартных // запросов технологии LINQ using System; using System.Linq; using System.Windows.Forms; // Другие директивы using удалены, поскольку они не используются в данной программе namespace Linq1 { public partial class Form1: Form { public Form1() { InitializeComponent(); this.Text = "Технология LINQ"; textBox1.Multiline = true; // ЗАДАЧА 1: // Из массива имен выбрать имена с количеством букв равным шести, // вывести эти имена в текстовое поле TextBox в алфавитном порядке, при // этом все буквы перевести в верхний регистр. // Решение: string СтрокаИмен = "Витя Лариса Лариса Лена Андрей Женя " + "Александр Лариса Виктор Света Оксана Наташа"; // Из строки имен получаем массив имен, задавая в качестве сепаратора // деления подстрок символ пробела: string[] Имена = СтрокаИмен.Split(' '); // или проще: string[] Имена = // { "Витя", "Лариса", "Лариса", "Лена", "Андрей", "Женя", // "Александр", "Лариса", "Виктор", "Света", "Оксана", "Наташа" }; textBox1.Text = "ЗАДАЧА 1. В списке имен:\r\n\r\n"; foreach (string x in Имена) textBox1.Text = textBox1.Text + x + " "; // В результате LINQ-запроса получаем список имен с количеством букв // равным шести: var Запрос = from s in Имена where s.Length == 6 // - условие выбора orderby s // - сортировать в алфавитном порядке select s.ToUpper(); // - перевод в верхний регистр // s - это переменная диапазона схожа с переменной итерации в foreach // Удаляем элементы-дубликаты из списка имен: Запрос = Запрос.Distinct(); // Или таким образом: // Запрос = Запрос.Union(Запрос); textBox1.Text = textBox1.Text + "\r\n\r\n" + "выбираем имена с количеством букв равным шести, при " + "этом избавляемся от дублирования имен:\r\n\r\n"; foreach (string x in Запрос) // x - переменная итерации в цикле foreach textBox1.Text = textBox1.Text + x + " "; textBox1.Text = textBox1.Text + "\r\n\r\n"; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ЗАДАЧА 2: Из массива целых чисел X[] требуется выбрать числа, // значения которых >= 4, и записать эти числа в список Y, // отсортировав выбранные числа по возрастанию. // Решение: // Инициализация массива целых чисел: int[] X = { -2, 5, -23, 0, 7, -10, 11, 11, 14, 3, 8, 5, -5, 27, 8 }; textBox1.Text += "ЗАДАЧА 2. Из заданного массива X:\r\n\r\n"; foreach (int x in X) textBox1.Text = textBox1.Text + x + " "; textBox1.Text = textBox1.Text + "\r\n\r\nвыбираем числа, значения " + "которых >= 4 и записываем их в список (коллекцию) Y, " + "исключая элементы-дубликаты:\r\n\r\n"; // Y - это список, куда помещается выбранные элементы: var Y = from x in X where x >= 4 // - условие выбора orderby x // - сортируем по возрастанию select x; // Таким образом можно получить результат запроса в массив: // int[] Y = (from x in X // Здесь Y - это уже массив; // where x >= 4 // - условие выбора; // orderby x // - сортируем по возрастанию; // select x).ToArray(); // - преобразование списка в массив // Удаляем элементы-дубликаты из списка целых чисел: var Z = Y.Distinct(); // Или таким образом: // var Z = Y.Union(Y); // Вывод элементов списка Y в метку textBox1: foreach (var z in Z) textBox1.Text = textBox1.Text + z.ToString() + " "; } } } Как видно из программного кода, после присвоения массиву Имена начальных значений создаем запрос, который предусматривает выбор (select) из (from) массива Имена строк длиной (Length) ровно шесть символов (условие where). Запись выбранных имен выполняется в список Запрос с сортировкой списка в алфавитном порядке имен. Далее для удаления повторяющихся имен в списке используем функцию Distinct. В комментарии показано, как можно для этой же цели использовать функцию union, которая, вообще говоря, находит объединение двух множеств, т. е. выбирает в двух списках одинаковые элементы с удалением повторяющихся элементов. Поскольку мы объединяем два одинаковых списка, то получаем просто удаление повторяющихся элементов. Цикл foreach выводит список Запрос в текстовое поле textBox1. Следующая задача, решенная в данном программном коде, аналогична. Задан массив целых чисел X. Из этого массива выбираем в список Y элементы массива, значения которых больше или равны четырем. В комментарии показано, как можно записать результаты LINQ-запроса в массив. Удаление повторяющихся элементов в списке выполнено также с использованием функции Distinct. На рис. 19.1 приведен фрагмент работы программы.
Рисунок 19.1 - LINQ-запросы к массивам данных Убедиться в работоспособности программы можно, открыв решение Linq1.sln папки Linq1. Листинг 19.2. Извлечение данных из списков // Решаем три различных задачи по выбору элементов (объектов) из списка с помощью // стандартных запросов технологии LINQ using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; // Другие директивы using удалены, поскольку они не используются в данной программе namespace Linq2 { public partial class Form1: Form { public Form1() { InitializeComponent(); this.Text = "Технология LINQ"; textBox1.Multiline = true; // ЗАДАЧА 1. Из списка строк выбрать нужные записи задав условие выбора textBox1.Text = "ЗАДАЧА 1: Из списка имен:\r\n"; // Объявление списка строк и его заполнение: var Список = new List<string> { "Витя", "Света", "Андрей", "Лариса", "Маша", "Наташа" }; // или var Список = new List<string>(); // - список строк // Список.Add("Витя"); Список.Add("Света"); Список.Add("Андрей"); // Список.Add("Лариса"); Список.Add("Маша"); Список.Add("Наташа"); // Некоторые манипуляции со списком: int n = Список.Count; // Кол-во элементов в списке: // Получение из списка его элемента с индесом 3 (как в массиве): string A = Список.ElementAt<string>(4); Boolean Ответ = Список.Remove("Лариса"); // - удаление из списка // Преобразовать список в строковый массив: string[] МассивСтрок = Список.ToArray(); foreach (var x in Список) textBox1.Text = textBox1.Text + x.ToString() + " "; textBox1.Text += "\r\nвыбираем имена длиной четыре символа:\r\n"; // СписокВыбранныхИмен - это новый список, куда попадают выбранные // строки в результате LINQ-запроса: var СписокВыбранныхИмен = from Имя in Список where Имя.Length == 4 // - условие выбора orderby Имя // - сортировать список Z select Имя; // Вывод списка выбранных имен в текстовое поле textBox1: foreach (var x in СписокВыбранныхИмен) textBox1.Text = textBox1.Text + x.ToString() + " "; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ЗАДАЧА 2. textBox1.Text += "\r\n\r\nЗАДАЧА 2: Из списка сотрудников предприятия " + "выбираем не курящих для повышения зарплаты:\r\n\r\n"; // Заполняем список сотрудников: List<Сотрудник> Сотрудники = new List<Сотрудник>{ new Сотрудник {Имя="Карапузова Ирина", Возраст=27, КуритЛи=true }, new Сотрудник {Имя="Зиборов Виктор", Возраст=47, КуритЛи=false }, new Сотрудник {Имя="Ломачинская Светлана", Возраст=34, КуритЛи=false }, new Сотрудник {Имя="Стороженко Светлана", Возраст=34, КуритЛи=false }, new Сотрудник {Имя="Еременко Татьяна", Возраст=34, КуритЛи=true }, new Сотрудник {Имя="Погребицкий Олег", Возраст=42, КуритЛи=true }, }; var СписокНекурящихСотрудников = from Сотрудник in Сотрудники where Сотрудник.КуритЛи == false orderby Сотрудник.Имя select Сотрудник; // Вывод списка некурящих сотрудников в текстовое поле textBox1: foreach (var x in СписокНекурящихСотрудников) textBox1.Text = textBox1.Text + string.Format("{0} - возраст " + "- {1}\r\n", x.Имя, x.Возраст); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ЗАДАЧА 3. textBox1.Text += "\r\nЗАДАЧА 3: Из списка студентов факультета " + "выбираем двоечников:\r\n\r\n"; // Каждый элемент в списке содержит фамилию студента и полученные // им текущие оценки: List<Студент> Студенты = new List<Студент> { new Студент {Фамилия="Зиборов", Оценки= new List<int> {5, 4, 4, 5}}, new Студент {Фамилия="Стороженко", Оценки= new List<int> {3, 3, 2, 3}}, new Студент {Фамилия="Ломачинская", Оценки= new List<int> {3, 4, 4, 5}}, new Студент {Фамилия="Погребицкий", Оценки= new List<int> {2, 4, 3, 2}}, new Студент {Фамилия="Левочкин", Оценки= new List<int> {3, 3, 4, 3}} }; // Для доступа к внутреннему списку оценок предложение From // используем два раза: var СписокДвоечников = from Студент in Студенты from Оценка in Студент.Оценки where Оценка <= 2 orderby Студент.Фамилия select new { Студент.Фамилия, Оценка }; foreach (var Студик in СписокДвоечников) textBox1.Text += string.Format("Студент {0} " + "имеет оценку: {1}\r\n", Студик.Фамилия, Студик.Оценка); // Строка со студентом Погребицким выводится два раза, поскольку он // имеет две двойки } } // Объявляем класс, содержащий имя сотрудника, его возраст, а также // информацию, курит ли он: public class Сотрудник { public string Имя { get; set; } public int Возраст { get; set; } public bool КуритЛи { get; set; } } // Объявляем класс, содержащий фамилию студента и список полученных им оценок: public class Студент { public string Фамилия { get; set; } public List<int> Оценки { get; set; } } }
Первая задача довольно простая и очень похожа на задачи, которые мы решали с помощью технологии LINQ в предыдущем примере. Здесь, в этой новой задаче вместо массива имен требуется создать список имен, а далее из этого списка выбрать имена длиной четыре символа. Решение этой задачи, построение LINQ- запроса аналогично решению задачи из предыдущего примера, отличие состоит лишь в применении синтаксиса манипуляций со списком типа List, а не с массивом. Здесь также приведены некоторые важные техники для манипуляции списком, в частности получение элемента списка по указанному индексу (аналогия с массивом), удаление элемента, преобразование списка в строковый массив. Вторая задача заключается в том, чтобы создать список сотрудников предприятия и из этого списка выбрать некоторых сотрудников по какому-либо признаку, например тех, кто не курит. При создании списка объявлен класс Сотрудник, который содержит три свойства: Имя, Возраст и булеву переменную КуритЛи. В начале решения заполняем список сотрудников, а затем строим LINQ-запрос для заполнения списка некурящих сотрудников. Этот список выводим в текстовое поле textBox1, используя цикл foreach. Третья задача немного сложнее. Требуется создать список студентов факультета, содержащий фамилию студента и список полученных им текущих оценок, т. е. список оценок должен быть "вложен" в список студентов. Из списка студентов необходимо выбрать тех, кто имеет в списке своих оценок хотя бы одну двойку. Для решения этой задачи вначале объявляем новый класс Студент, который имеет в качестве свойств класса фамилию студента и список (типа List) оценок. Далее в начале решения третьей задачи мы привели синтаксис заполнения списка студентов. Затем строим LINQ-запрос, где, поскольку нам необходимо искать элемент списка внутри "вложенного" списка, мы используем предложение From два раза. Поскольку студент Погребицкий имеет две двойки в списке своих текущих оценок, он в списке двоечников фигурирует дважды (рис. 19.2). Рисунок 19.2 - Три LINQ-запроса к спискам данных Убедиться в работоспособности программы можно, открыв решение Linq2.sln папки Linq2. Листинг 19.3. Группировка элементов списка с помощью LINQ-запросов // Программа формирует список некоторых продуктов питания. Первый LINQ-запрос // группирует элементы списка по критерию цены: в первом списке оказываются // продукты, цена за единицу которых меньше или равна 90 руб., а во втором, // соответственно, больше 90 руб. Второй LINQ-запрос вычисляет среднюю цену // продукта по каждой группе. Результаты запросов выводятся в текстовое поле. using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; // Другие директивы using удалены, поскольку они не используются в данной программе namespace LinqЦеныНаПродукты { public partial class Form1: Form { public Form1() { InitializeComponent(); textBox1.Multiline = true; base.Text = "Группировка элементов списка с помощью LINQ-запроса"; // Заполняем список продуктов: List<Продукт> Продукты = new List<Продукт>{ new Продукт {Наименование="Творог", Цена=112.50F }, new Продукт {Наименование="Хлеб", Цена=18.75F }, new Продукт {Наименование="Печенье", Цена=93.75F }, new Продукт {Наименование="Чай", Цена=76.25F }, new Продукт {Наименование="Мясо", Цена=150.00F }, new Продукт {Наименование="Гречка", Цена=62.50F }, }; var Запрос1 = from П in Продукты group П by new { Критерий = П.Цена > 90, } into g select g; var Запрос2 = from p in Продукты group p by p.Цена > 90 into g select new { g.Key, СредЦенаПоГруппе = g.Average(p => p.Цена) }; Single СредЦенаПоГруппе1 = Запрос2.ElementAt(0).СредЦенаПоГруппе; Single СредЦенаПоГруппе2 = Запрос2.ElementAt(1).СредЦенаПоГруппе; // Вывод результатов обоих запросов в текстовое поле: foreach (var Группа in Запрос1) { if (Группа.Key.Критерий == false) textBox1.Text += "\r\nЦены 90 руб или меньше:"; else textBox1.Text += "\r\nЦены больше 90 руб:"; foreach (var Прод in Группа) { textBox1.Text += String.Format("\r\n{0} - {1}", Прод.Наименование, Прод.Цена); } if (Группа.Key.Критерий == false) textBox1.Text += String.Format( "\r\nСредняя цена по данной группе = {0} руб.\r\n", СредЦенаПоГруппе2); else textBox1.Text += String.Format( "\r\nСредняя цена по данной группе = {0} руб.\r\n", СредЦенаПоГруппе1); } } } public class Продукт { public String Наименование { get; set; } public Single Цена { get; set; } } } В начале программы формируем список продуктов питания. Для этого объявляем новый класс продукт, в котором для каждого продукта задаем два поля: наименование продукта и его цену. После заполнения списка продуктов (для упрощения в этом списке всего шесть продуктов) задаем первый LINQ-запрос, обеспечивающий деление списка на две группы. Второй LINQ-запрос вычисляет среднюю цену продукта по каждой группе. Вывод результатов обоих запросов организуем с помощью двух вложенных циклов foreach. Фрагмент работы программы показан на рис. 19.3. Рисунок 19.3 - Группировка списка с помощью LINQ-запросов Убедиться в работоспособности программы можно, открыв решение LinqЦеныНаПродукты.sln папки LinqЦеныНаПродукты. 5.4 LINQ-запрос к словарю данных Dictionary Замечательной структурой данных является словарь Dictionary. Он представляет собой совокупность (коллекцию) ключей и значений. То есть каждый элемент (запись), добавляемый в словарь, состоит из значения Value и связанного с ним ключа Key. Извлечение значения по его ключу происходит очень быстро, поскольку класс Dictionary<Key,Value> реализован как хэш-таблица. Каждый ключ в словаре Dictionary<Key,Value> должен быть уникальным, т. е. единственным в своем роде, эксклюзивным. При добавлении в коллекцию Dictionary очередного элемента так называемый компаратор проверяет на равенство уникальность нового ключа. Ключ не может быть пустым (null), а значение может, если тип значения value является ссылочным типом. Возможно создание словаря, в котором не различается регистр символов. Использование словаря Dictionary может существенно повлиять на эффективность алгоритма, на простоту его понимания и легкость программной реализации. Задача, решаемая в данном примере, состоит в том, чтобы продемонстрировать возможность выбора элементов из словаря данных Dictionary с помощью LINQ-запроса. В начале программы зададим массив сотрудников некого учреждения, а затем массив сотрудников преобразуем в словарь Dictionary. Причем в качестве ключа к каждому элементу словаря зададим имя сотрудника, которое является уникальным. По ключу можно получить все остальные сведения о сотруднике, записанные в словарь. Кроме того, с помощью LINQ-запроса к словарю можно получать новую коллекцию сотрудников по какому-либо условию (предложение where). Здесь мы зададим выбор сотрудников, чей возраст превышает 33 года (возраст Иисуса Христа). ’ Для решения этой задачи запустим Visual Studio 2010 и выберем проект шаблона Console Application, укажем имя Name — LinqDictionary. Затем на вкладке программного кода введем текст, представленный в листинге 19.4. Листинг 19.4. Организация LINQ-запроса к словарю Dictionary // Задаем массив сотрудников учреждения. Из этого массива создаем словарь // сотрудников, а в качестве ключа к этому словарю выбираем имя сотрудника. // С помощью LINQ-запроса из массива сотрудников выбираем тех, чей возраст // превышает 35 лет. При выводе результата запроса на печать учитываем, что // говоря про возраст, мы говорим "47 лет", но "34 года". То есть если из возраста // вычесть число кратное 10, то при остатке меньше 5, говорят, например, "34 года", // а при остатке больше или равно 5, говорят "47 лет". using System; using System.Linq; // Другие директивы using удалены, поскольку они не используются в данной программе namespace LinqDictionary { class Program { static void Main(string[] args) { Console.Title = "LINQ-запрос к словарю Dictionary"; // Создаем массив сотрудников учреждения: var Сотрудники = new[] { new {Имя = "Карапузова Ирина", Возраст = 27, КуритЛи = true }, new {Имя = "Зиборов Виктор", Возраст = 47, КуритЛи = false }, new {Имя = "Ломачинская Светлана", Возраст = 31, КуритЛи = false }, new {Имя = "Стороженко Светлана", Возраст = 34, КуритЛи = false }, new {Имя = "Еременко Татьяна", Возраст = 22, КуритЛи = true }, new {Имя = "Погребицкий Олег", Возраст = 42, КуритЛи = true } }; // Доступ к элементу массива Сотрудники можем иметь через его индекс: var t = Сотрудники[2]; // Строим LINQ-запрос к массиву сотрудников; выбираем тех, возраст // которых больше 33 лет: // var СписокВзрослыхСотрудников = from Сотрудник in Сотрудники // where Сотрудник.Возраст >= 33 // orderby Сотрудник.Имя // select Сотрудник; // Из массива сотрудников создаем словарь сотрудников, в котором // ключом является имя сотрудника: var СловарьСотрудников = Сотрудники.ToDictionary(Ключ => Ключ.Имя); // В этом случае очень удобным становится доступ к сведениям о // сотруднике по его имени: Boolean КуритЛиЗиборов = СловарьСотрудников["Зиборов Виктор"].КуритЛи; int ВозрастЗиборова = СловарьСотрудников["Зиборов Виктор"].Возраст; Console.WriteLine("Сотруднику Зиборову Виктору - {0} лет\n", ВозрастЗиборова); // Строим LINQ-запрос к словарю сотрудников; выбираем тех, возраст // которых больше 33 лет: var СписокВзрослыхСотрудников = from Сотрудник in СловарьСотрудников where Сотрудник.Value.Возраст >= 33 orderby Сотрудник.Value.Имя select new { Сотрудник.Key, Сотрудник.Value.Возраст, ЛетИлиГода = Сотрудник.Value.Возраст - 10F * Math.Truncate(Сотрудник.Value.Возраст / 10F) >= 5 };
// Вывод результата запроса на консоль: Console.WriteLine("Список сотрудников, старше 33 лет:"); foreach (var x in СписокВзрослыхСотрудников) Console.WriteLine("{0}, возраст - {1} {2} ", x.Key, x.Возраст, x.ЛетИлиГода? "лет": "года"); Console.ReadKey(); } } } Представленный текст программы очевиден. Вначале задаем массив сотрудников учреждения, в этом массиве всего 6 элементов. В комментарии показано, как можно организовать LINQ-запрос к заданному массиву. Далее массив конвертируем в словарь сотрудников, задавая в качестве ключа имя сотрудника. Затем организуем LINQ-запрос к словарю Dictionary, выбираем в новую коллекцию (список) тех, чей возраст превышает 33 года. Учитываем, что при выводе на консоль списка выбранных сотрудников мы говорим "47 лет", но "34 года". То есть если из возраста вычесть число, кратное 10, то при остатке меньше 5 говорят, например, "34 года", а при остатке больше или равном 5 говорят "47 лет". Число, кратное 10, мы вычисляем, используя функцию Math.Truncate, которая возвращает целую часть числа, поданную на ее вход. В этом алгоритме мы использовали булеву переменную ЛетИлиГода, которая определяет (по принципу "да" или "нет") следует писать "лет" или "года". Результат работы программы показан на рис. 19.4
Рисунок 19.4 - Запрос к словарю данных на "взрослых" сотрудников Убедиться в работоспособности программы можно, открыв решение LinqDic- tionary.sln папки LinqDictionary. Листинг 19.5. Создание XML-документа представляющего телефонную книгу. // Программа создает типичный XML-документ. С ее помощью можно разобраться в // структуре XML-документа. В комментариях приведена терминология содержимого // XML-документа: корневой элемент, вложенные элементы, имя элемента и его // значение, а также атрибуты элемента, их имена и значения. // XML-документ представляет телефонную книгу, содержащую имя контакта, номер // домашнего телефона, а также мобильного. Программа после создания XML-документа // отображает его на консоли, а также записывает его в файл. Если этот файл открыть // с помощью MS Excel, то мы получим таблицу из трех столбцов. using System; using System.Xml.Linq; // Другие директивы using удалены, поскольку они не используются в данной программе namespace LinqСоздатьXML_документ { class Program { static void Main(string[] args) { Console.Title = "Корневой элемент XML-документа"; // Создаем новый XML-документ: XDocument XMLдокумент = new XDocument( // Комментарий в XML-документе: new XComment("Телефонная_книга - это корневой элемент XML-документа:"), new XElement("Телефонная_книга", // - имя корневого элемента
new XComment("Элемент СТРОКА содержит атрибут Контакт и два вложенных элемента"), new XElement("СТРОКА", // - имя (Name) элемента new XAttribute("Контакт", "Олег"), new XElement("Домашний_телефон", "236-23-67"), // - имя элемента и его значение new XElement("Мобильный_телефон", "+7(495)625-31-43")),
new XComment("Атрибут Контакт имеет значение 'Прогноз погоды':"), new XElement("СТРОКА", new XAttribute("Контакт", "Прогноз погоды"), // - атрибут элемента СТРОКА new XElement("Домашний_телефон", "001"), new XElement("Мобильный_телефон", "")), // - имя элемента и его зачение (Value)
new XComment("Поскольку каждый элемент Контакт имеет атрибут и два вложенных=>"), new XElement("СТРОКА", new XAttribute("Контакт", "Борис Григорьевич"), // - имя атрибута - Контакт new XElement("Домашний_телефон", "402-12-45"), new XElement("Мобильный_телефон", "+7(495)536-79-94")),
new XComment("=> элемента, в MS Excel отобразится таблица с тремя колонками"), new XElement("СТРОКА", new XAttribute("Контакт", "Света"), // - значение атрибута - Света new XElement("Домашний_телефон", ""), new XElement("Мобильный_телефон", "+7(495)615-24-41"))) ); // Сохранить XML-документ: XMLдокумент.Save(@"C:\Зиборов.XML"); Console.WriteLine(XMLдокумент); Console.ReadKey(); } } }
Чтобы понять текст программы, рассмотрим структуру полученного XML- файла, а для этого откроем этот файл с помощью Internet Explorer (рис. 19.5). Здесь весь XML-документ вложен в так называемый корневой элемент между начальным тегом <Телефонная_книга> и конечным тегом </Телефонная_книга>. Четыре элемента СТРОКА вложены в корневой элемент. В соответствующей таблице MS Excel элементы СТРОКА будут представлять строку в таблице. В свою очередь элемент СТРОКА содержит в себе атрибут Контакт и два вложенных в него элемента, имена (Name) которых— Домашний_телефон и Мобильный_телефон. Именно поэтому в MS Excel отобразится таблица с тремя колонками (один атрибут и два элемента): "Контакт", "Домашний_телефон" и "Мобильный_телефон". Элемент может иметь один или несколько атрибутов (а может и не иметь, как, скажем, элемент Домашний_телефон), например, первый элемент СТРОКА имеет атрибут с именем (Name) Контакт и со значением атрибута (Value) — 001. После запуска данной программы будет выведено на консоль содержимое XML-документа (без XML-объявления), а также будет создан XML-файл. Открыв этот файл с помощью MS Excel, получим таблицу телефонных контактов (рис. 19.6).
Рисунок 19.5 - XML-файл, открытый в Internet Explorer
Рисунок 19.6 - XML-файл, открытый в MS Excel Убедиться в работоспособности программы можно, открыв решение LinqСоздатьXML-документ.sln папки LinqСоздатьXML-документ. Листинг 19.6. Извлечение значения элемента из XML-данных // Дана строка XML, содержащая прогнозные метеорологические показатели для // г. Москвы на заданную дату. Программа извлекает из корневого элемента // XML-документа значение температуры элемента "Температура": using System.Windows.Forms; //Другие директивы using удалены, поскольку они не используются в данной программе namespace Linq3 { public partial class Form1: Form { public Form1() { InitializeComponent(); this.Text = "LINQ-запрос к XML-данным"; textBox1.Multiline = true; string СтрокаXML = @"<?xml version=""1.0""?> <МетеорологическиеПоказатели> <Город>Москва</Город> <Дата>2010.05.15 06:30 UTC</Дата> <Температура> 64 F (18 C)</Температура> <Ветер>Сев-Вост 8 м/сек</Ветер> <Видимость>12 км</Видимость> <Влажность> 72%</Влажность> <Давление>760 мм рт ст</Давление> </МетеорологическиеПоказатели>"; // Загрузка корневого элемента из строки, содержащей XML: var КорневойЭлемент = System.Xml.Linq.XElement.Parse(СтрокаXML); // Или корневой элемент XML-документа получаем через файл: // Записываем строку, содержащую XML в файл: // System.IO.File.WriteAllText("ПоказателиПогоды.xml", СтрокаXML); // Загружаем корневой элемент XML: // var КорневойЭлемент = System.Xml.Linq. // XElement.Load("ПоказателиПогоды.xml"); // Из корневого элемента извлекаем вложенный в него элемент // "Температура" и получаем соответствующее значение (Value) этого // элемента: string Температура = КорневойЭлемент.Element("Температура").Value; textBox1.Text = "Строка XML:\r\n\r\n" + СтрокаXML + "\r\n\r\n"; textBox1.Text += "Значение температуры = " + Температура; } } } В начале текста программы задаем текстовую строку, содержащую XML- данные. Далее, используя метод Parse класса XElement пространства имен Linq, получаем корневой элемент XML-документа. В комментарии показано, как можно получить корневой элемент через запись/чтение XML-файла. Затем с помощью метода Element извлекаем значение (Value) элемента температура, которое выводим в текстовое поле. Фрагмент работы программы приведен на рис. 19.8. Рисунок 19.8 - Извлечение значения элемента из XML-документа
Рисунок 19.9 - Представление XML-данных в виде таблицы в MS Excel Убедиться в работоспособности программы можно, открыв решение Linq3.sln папки Linq3. Теперь решим похожую задачу по извлечению значения элемента, но пусть XML-данные представлены в другой форме, а именно каждый метеорологический показатель вложим в один и тот же элемент <Показатель> </Показатель>, в этом случае глубина вложенности элементов будет уже равна трем (см. листинг 19.7). Естественно спросить: что мы будем с этого иметь? Дело в том, что если соответствующий XML-файл открыть с помощью табличного редактора MS Excel, то мы сможем увидеть эти XML-данные в виде наглядной таблицы, даже не ссылаясь на таблицу стилей — файл XSLT (не путать с XLS-файлом), см. рис. 19.9. Теперь для получения значения температуры удобно воспользоваться типовым LINQ-запросом (листинг 19.7). Листинг 19.7. Извлечение значения элемента из XML-данных // Дана строка XML, которая содержит прогнозные метеорологические показатели для // г. Москвы на заданную дату. При этом каждый метеорологический показатель вложен // в один и тот же элемент <Показатель> </Показатель>. Это обеспечивает удобный // просмотр соответствующего XML-файла в MS Excel в виде таблицы. Программа находит // в корневом элементе данного XML-документа элемент "Температура" и извлекает из // него значение температуры. using System.Windows.Forms; using System.Linq; // Другие директивы using удалены, поскольку они не используются в данной программе namespace Linq4 { public partial class Form1: Form { public Form1() { InitializeComponent(); this.Text = "LINQ-запрос к XML-данным"; textBox1.Multiline = false; // Инициализация XML-строки: string СтрокаXML = @"<?xml version=""1.0""?> <МетеорологическиеПоказатели> <Показатель> <Город>Москва</Город> </Показатель> <Показатель> <Дата>2010.05.15 06:30 UTC</Дата> </Показатель> <Показатель> <Температура> 64 F (18 C)</Температура> </Показатель> <Показатель> <Ветер>Сев-Вост 8 м/сек</Ветер> </Показатель> <Показатель> <Видимость>12 км</Видимость> </Показатель> <Показатель> <Влажность> 72%</Влажность> </Показатель> <Показатель> <Давление>760 мм рт ст</Давление> </Показатель> </МетеорологическиеПоказатели>"; var КорневойЭлемент = System.Xml.Linq.XElement.Parse(СтрокаXML); // Или корневой элемент получаем через файл: // Записываем строку, содержащую XML в файл: // System.IO.File.WriteAllText("ПоказателиПогоды2.xml", СтрокаXML); // Загружаем корневой элемент: // var КорневойЭлемент = System.Xml.Linq.XElement.Load( // "ПоказателиПогоды2.xml"); // Запрос - это коллекция (список) строк, куда извлекаем значение // (Value) элемента "Температура": var Запрос = from x in КорневойЭлемент.Elements("Показатель") from y in x.Elements("Температура") select y.Value; // Таких строк в коллекции Запрос - одна textBox1.Text = "Значение температуры = "; foreach (var x in Запрос) textBox1.Text = textBox1.Text + x; } } } Как видно из программного кода, поиск организован в двух уровнях (два предложения from), сначала выбор в коллекцию всех элементов Показатель, а затем из этой коллекции поиск элементов Температура. Результат запроса записывается в коллекцию строк, где имеем ровно одну строку. Фрагмент работы программы показан на рис. 19.10. Рисунок 19.10 - LINQ-запрос к XML-документу Убедиться в работоспособности программы можно, открыв решение Linq4.sln из папки Linq4. Листинг 19.8. Извлечение значения элемента из XML-данных // Имеем XML-данные, в которых содержатся таблица с именами и телефонами, причем // имена в этой телефонной табличке повторяются. Задача состоит в том, чтобы в // данной таблице телефонов (представленной в виде XML) найти все строчки c // именем "Витя" с помощью LINQ-запроса. using System.Linq; using System.Windows.Forms; // Другие директивы using удалены, поскольку они не используются в данной программе namespace Linq5 { public partial class Form1: Form { public Form1() { InitializeComponent(); this.Text = "LINQ-запрос к XML-данным"; textBox1.Multiline = true; // Инициализация XML-строки: string СтрокаXML = @"<?xml version=""1.0""?> <ТаблицаТелефонов> <Строка> <Имена>Витя</Имена> <Номера_телефонов>274 28 44</Номера_телефонов> </Строка> <Строка> <Имена>Андрей</Имена> <Номера_телефонов>8-085-456-2378</Номера_телефонов> </Строка> <Строка> <Имена>Карапузова Таня</Имена> <Номера_телефонов>445-56-47</Номера_телефонов> </Строка> <Строка> <Имена>Витя</Имена> <Номера_телефонов>099 72 161 52</Номера_телефонов> </Строка> <Строка> <Имена>Никипелов</Имена> <Номера_телефонов>236-77-76</Номера_телефонов> </Строка> <Строка> <Имена>Зиборов</Имена> <Номера_телефонов>254 67 97</Номера_телефонов> </Строка> </ТаблицаТелефонов>"; var КорневойЭлемент = System.Xml.Linq.XElement.Parse(СтрокаXML); // Запись строки, содержащей XML в файл: // System.IO.File.WriteAllText("ТаблицаТелефонов.xml", СтрокаXML); // var КорневойЭлемент = System.Xml.Linq. // XElement.Load("ТаблицаТелефонов.xml"); var Записи = from x in КорневойЭлемент.Elements("Строка") where (string)x.Element("Имена") == "Витя" select x.Element("Номера_телефонов").Value; textBox1.Text = textBox1.Text + @"Строки, содержащие имя ""Витя"":" + "\r\n"; // Вывод коллекции записей в текстовое поле textBox1: foreach (var x in Записи) textBox1.Text = textBox1.Text + x + "\r\n"; // Таких записей в этой коллекции - ровно одна } } } Как видно, в начале программы мы инициализируем (т. е. присваиваем начальные значения) XML-строку. Далее извлекаем корневой элемент из XML-документа, он, по сути, отличается от XML-документа отсутствием XML-объявления (в этом можно убедиться в отладчике программы). В комментарии указано, как можно получить корневой элемент в том случае, если он представлен в виде XML-файла во внешней памяти. Затем организуем типовой, стандартный LINQ-запрос. Результат запроса попадает в коллекцию записей, которую выводим в текстовое поле, используя оператор цикла foreach. Фрагмент работы программы показан на рис. 19.12. Рисунок 19.12 - LINQ-запрос к XML-документу Убедиться в работоспособности программы можно, открыв решение Linq5.sln из папки Linq5. 5.8 LINQ-запрос к набору данных DataSet Весьма полезной оказывается организация LINQ-запросов к наборам данных DataSet, используемым, к примеру, при работе с базами данных. Объект класса DataSet представляет расположенный в памяти кэш (cache) данных (кэш — это промежуточная
|
||||
Последнее изменение этой страницы: 2016-04-26; просмотров: 677; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 13.59.83.202 (0.013 с.) |