1 Язык интегрированных запросов LINQ LINQ – это аббревиатура от Language-Integrated Query (язык интегрированных запросов). LINQ позволяет, не выходя за пределы синтаксиса Visual Basic, извлекать информацию из источников данных. LINQ является новым средством в Visual Studio 2008 и .NET Framework версии 3.5. К источникам данных, с которыми можно применять LINQ относятся: все объекты, поддерживающие интерфейс IEnumerable (такими объектами являются все массивы и коллекции.NET), наборы данных ADO.NET, база данных Microsoft SQL Server, XMLдокумент. 1. Структура запроса LINQ При необходимости извлечь информацию из источника данных нас обычно интересует не вся хранящаяся там информация, а только та, которая удовлетворяет некоторому критерию. Например, из базы данных о студентах вуза нас могут интересовать только студенты, обучающиеся на определенном курсе. Этот критерий, называющийся запросом, должен быть записан на LINQ. Запрос LINQ – это одна инструкция, состоящая из нескольких взаимосвязанных частей, определяющих источник данных и операции с данными. Порядок задания этих частей в запросе определен нестрого и в некоторых случаях допускает перемену мест частей запроса. Началом каждой части запроса служит определенное зарезервированное слово. Наиболее наглядно структуру запроса можно пояснять на примерах с массивами. Поэтому в первых примерах построения запросов источником данных будет служить массив. 2. Источник данных В первую очередь в запросе нужно указать источник данных, к которому выполняется запрос. Часть запроса, в которой задается источник данных, в запросе всегда располагается первой и начинается с зарезервированного слова From (от). В расположенной ниже подпрограмме Button1_Click содержится самый простой запрос из мыслимых запросов к массиву: Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click 1: Dim m() As Integer = {11, 0, 6, 3, 11, 4, 2, 6, 1, 15} 2: Dim q = From v In m 3: TextBox1.Clear() 4: For Each v1 In q 5: TextBox1.AppendText(v1 & " ") 6: Next End Sub В первой строке тела подпрограммы объявлен и одновременно инициализирован массив m целого типа. Во второй строке объявлен запрос с именем q элементов v из массива m. Объект q здесь создается системой как коллекция, содержащая целочисленные элементы. Обратите внимание, целый тип переменной v в этом предложении объявлен системой автоматически. Поскольку никакого критерия отбора в запрос элементов массива нет, то в результате выполнения этой строки будет создана коллекция, которая будет содержать все элементы массива m. В строках 3 – 6 содержатся инструкции, обеспечивающие отображение в текстовом поле всех элементов запроса q. Содержащаяся в четвертой строке переменная v1 целого типа объявлении системой также автоматически. В результате выполнения подпрограммы Button1_Click в текстовом поле TextBox1 появится строка: 11 0 6 3 11 4 2 6 1 15. 2 3. Фильтрация Фильтрация – это отбор из источника только тех элементов данных, которые удовлетворяют заданному условию. Условие фильтрации задается в разделе Where (куда) запроса. Условием фильтрации может быть любое логическое выражение. Запрос вернет только те элементы, для которых условие фильтра примет значение True. Например, для выборки из массива m только тех элементов, значение которых больше 5, в рассмотренной в предыдущем разделе подпрограмме Button1_Click вторая строка должна быть: Dim q = From v In m Where v > 5. Теперь в результате выполнения подпрограммы в текстовом поле TextBox1 появится строка: 11 6 11 6 15. 4. Операции статистической обработки Статистическая операция является функцией всех значений из коллекции запроса. В табл. 1 перечислены основные стандартные статистические операции, которые можно применять в запросах: Статистические операции LINQ. Таблица 1 Имя операции Описание Синтаксис выражения запроса Visual Basic Average Вычисляет среднее значение коллекции значений. Aggregate … In … Into Average() Count Подсчитывает число элементов в коллекции (при необходимости только те элементы, которые удовлетворяют функции предиката). Aggregate … In … Into Count() Max Определяет максимальное значение в коллекции. Aggregate … In … Into Max() Min Определяет минимальное значение в коллекции. Aggregate … In … Into Min() Sum Вычисляет сумму значений в коллекции. Aggregate … In … Into Sum() Пример вычисления суммы всех элементов запроса: Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click Dim m() As Integer = {11, 0, 6, 3, 11, 4, 2, 6, 1, 15} Dim q = From v In m _ Where v > 5 Dim r = Aggregate v1 In q Into Sum() TextBox1.Clear() TextBox1.AppendText("Результат запроса: " & vbCrLf) For Each v In q TextBox1.AppendText(v & vbCrLf) Next TextBox1.AppendText("Итого: " & r & vbCrLf) End Sub Подпрограмма Button1_Click выведет в текстовом поле TextBox1: 3 Результат запроса: 11 6 11 6 15 Итого: 49 5. Упорядочение (сортировка) Часто бывает удобно упорядочить возвращенные данные в определенном порядке. Упорядочение данных задается в разделе Order By (согласно порядку). Она позволяет располагать данные в порядке возрастания (Ascending) или в порядке убывания (Descending) одного или нескольких признаков. В результате выполнения запроса: Dim q = From v In m Where v > 5 Order By v Ascending в текстовом поле TextBox1 будет выведена строка: 6 6 11 11 15. А вот следующий запрос сначала выполняет сортировку по количеству разрядов числа, а уже затем – по значению числа: Dim q = From v In m Order By v.ToString.Length _ Order By v Descending Здесь метод ToString преобразует число в строку, затем метод Length возвращает длину строки. Теперь в текстовом поле будет выведено: 15 11 11 6 6 4 3 2 1 0. 6. Удаление повторяющихся значений Иногда требуется, чтобы возвращаемые запросом значения не повторялись. Это требование задается словом Distinct (разный). Например, если нас интересует перечень всех разных значений элементов, содержащихся в массиве m, то он может быть получен запросом: Dim q = From v In m Distinct Order By v Ascending Этот запрос вернет строку: 0 1 2 3 4 6 11 15. 7. Группировка Можно в запрос добавить слово Group By для группировки элементов в результатах запроса по одному или нескольким полям элементов. Например, это можно применить для вывода списка сотрудников организации по отделам. Сначала в список должны входить все сотрудники первого отдела, затем все сотрудники второго отдела и т.д. 8. Выборка (проекция) Если в результате запроса требуется получать не просто копии элементов источника данных, а выполнить требуемое их преобразование, то это можно сделать в разделе Select запроса. Например, запрос Dim q = From v In m Select v ^ 2 + 1 в результате вернет строку 122 1 37 10 122 17 5 37 2 226. 9. Объединение источников При указании в разделе From более одного источника данных LINQ выполняет декартово произведение этих источников с последующей их фильтрацией. В качестве примера рассмотрим запрос в подпрограмме Button2_Click: Private Sub Button2_Click(ByVal sender As System.Object, _ 4 ByVal e Dim Dim Dim As System.EventArgs) Handles Button2.Click m1() As Integer = {0, 1, 2} m2() As Integer = {6, 7} q = From v1 In m1, v2 In m2 _ Select v1 + v2 TextBox1.Clear() For Each v In q TextBox1.AppendText(v & vbTab) Next End Sub При выполнении этого запроса разделом From будут просмотрены все возможные пары чисел m1 и m2, а именно: (0, 6), (0, 7), (1, 6), (1, 7), (2, 6), (2, 7). После выполнения выборки программа выдаст: 6 7 7 8 8 9. 10. Учебная база данных «Библиотека2» В качестве примера рассмотрим учебную базу данных Библиотека2, содержащую информацию о книгах библиотеки, созданную с помощью СУБД Access. Работа с базами данных другого типа проходит аналогично. В базе данных Библиотека2 нет ограничения для количества авторов книги. Для этого между таблицами Книги и Авторы установлено отношение «многие ко многим», которое обеспечивает дополнительная связующая таблица КнгАвт. Вся информация в этой базе данных содержится в четырех таблицах: Книги, Авторы, Издательства и КнгАвт. Полное представление о структуре этих таблиц дают рис. 1 – 3. Рис. 4 показывает связь, установленную между таблицами. Выделенные жирно начало и конец линии связи означает, что эта связь обеспечивает целостность данных. Рис. 1. Структура таблицы Книги 5 Рис. 2. Структура таблицы Авторы и таблицы Издательства Рис. 3. Структура связующей таблицы КнгАвт 6 Рис. 4. Связь данных 11. Создание проекта «Библиотека2» Для подготовки к выполнению задания на компьютере нужно выполнить следующие действия: 1. Создать на диске d свою рабочую папку. 2. Скопировать в рабочую папку базу данных Библиотека2. Этот файл находится в папке K:\FP\Inf.Net\Кладовка. 3. Открыть приложение Microsoft Visual Studio 2008. 4. Создать новый проект по шаблону Windows Forms Application с именем Библиотека2. В поле Location следует указать путь к своей рабочей папке. 5. Чтобы каждая из четырех таблиц базы данных могла размещаться на отдельной форме следует создать в проекте еще три формы Form2, Form3 и Form4. Еще одна форма Form5 потребуется для создания и отображения запросов. Создайте ее в проекте. Чтобы было удобнее ориентироваться в характере отображаемой на форме информации, задайте свойству Text каждой формы соответствующее значение: Form1.Text – Книги, Form2.Text – Авторы, Form3.Text – Издательства, Form4.Text – КнгАвт и Form5.Text – Запросы. 6. Экземпляр формы Form1 создается системой автоматически. Для создания экземпляра каждой из остальных четырех форм следует добавить в проект модуль Module1: Module Module1 Public frm2 As New Form2 Public frm3 As New Form3 Public frm4 As New Form4 Public frm5 As New Form5 End Module 7. На форме Form1 следует поместить кнопку Button1, кнопку Button2, кнопку Button3 и кнопку Button4. После запуска проекта отображается форма Form1. Кнопка Button1 позволит скрыть форму Form1 и отобразить форму Form2. Кнопка Button2 позволит скрыть форму Form1 и отобразить форму Form3. Кнопка Button3 позволит скрыть форму Form1 и отобразить форму Form4. Наконец, кнопка Button4 позволит скрыть форму Form1 и отобразить форму Form5. Задайте свойству Text каждой из этих кнопок соответствующее значение: Авторы, Издательства, КнгАвт, Запросы. 8. На формах Form2, Form3, Form4 и Form5 следует поместить по одной кнопке Button1. Эта кнопка позволит после отображения соответствующей формы при необходимости скрыть ее и отобразить форму Form1. Задайте свойству Text каждой из этих кнопок значение Книги. 9. Свяжите с кнопками Button1, Button2, Button3 и Button4 формы Form1 соответствующий код, указанный в листинге 1: 7 Листинг 1. Код подпрограмм Button1_Click, Button2_Click, Button3_Click и Button4_Click Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click Form2.Show() Me.Hide() End Sub Private Sub Button2_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button2.Click Form3.Show() Me.Hide() End Sub Private Sub Button3_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button3.Click Form4.Show() Me.Hide() End Sub Private Sub Button4_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button3.Click Form5.Show() Me.Hide() End Sub 10. Чтобы с каждой формы можно было вернуться к главной форме Form1, свяжите с кнопками Button1 форм Form2, Form3, Form4 и Form5 код, указанный в листинге 2: Листинг 2. Код подпрограмм Button1_Click форм Form2, Form3, Form4 и Form5 Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click Me.Hide() Form1.Show() End Sub 12. Установка соединения с базой данных Для соединения с базой данных нужно: 1. Выполнить команду View, Server Explorer (обозреватель серверов). 2. На панели инструментов (рис. 5) появившегося окна Server Explorer щелкните на кнопке Connect to Database (подключиться к базе данных). Connect to Database (подключиться к базе данных) Рис. 5. Окно обозревателя серверов 3. Теперь в открывшемся окне Add Connection (добавить соединение) нужно выбрать тип базы данных, с которой будет установлена связь. В поле Data Source 8 (источник данных) этого окна должно быть установлено значение Microsoft Access Database File (OLE DB). Если это не так, то нужно щелкнуть справа от этого поля на кнопке Change (изменить) и в открывшемся диалоговом окне Change Date Source (предпочитаемый источник данных) установить требуемый тип базы данных Microsoft Access Database File. Закройте окно Change Date Source щелком на кнопке OK. 4. В диалоговом окне Add Connection следует щелкнуть на кнопке Browse и указать путь к файлу базы данных Библиотека2, находящемуся в рабочей папке. Ваш экран должен соответствовать рис. 6. 5. Ничего больше не изменяя в окне Add Connection, нужно щелкнуть на кнопке Test Connection (Проверить подключение). Visual Studio попытается установить соединение с базой данных. Если появится сообщение Test Connection Succeeded (Проверка подключения выполнена), это будет означать, что провайдер выбран правильно и база данных имеет правильный формат. Окно с сообщением следует закрыть Рис. 6. Окно добавления соединения с базой нажатием на кнопку ОК, а также данных нажатием на кнопку ОК следует закрыть окно Add Connection. 13. Создание набора данных 1. Следует открыть окно Data Sources (источники данных). Это можно сделать щелчком на вкладке Data Sources. Обычно она находится справа под окном решений Solution Explorer. Иначе это можно сделать, выполнив команду меню Data, Show Data Sources. 2. В окне Data Sources нужно щелкнуть на ссылке Add New Data Source (добавить новый источник данных). 3. В открывшемся окне Data Source Configuration Wizard (Мастер конфигурации источника данных) следует выделить тип источника DataBase и щелкнуть на кнопке Next (Дальше). В открывшемся окне следует снова щелкнуть на кнопке Next и щелчком на кнопке Нет закрыть окно с предложением копировать данные. Снова нужно щелкнуть на кнопке Next. 4. Теперь следует указать таблицы и поля, данные из которых Вы хотите иметь в наборе данных. Для этого раскройте узлы Tables (таблицы), Авторы, Книги, Издательства (рис. 17.7) и поставьте галочки напротив всех четырех таблиц, со всеми полями которых будет связан создаваемый набор данных. Затем нажатием на кнопке Finish нужно завершить создание набора данных. В окне Data Sources, а также в окне решений Solution Explorer отобразится созданный набор данных – объект Библиотека2DataSet. 9 Рис. 7. Заключительный вид окна конкретизации запрашиваемой информации 14. Отображение информации Элемент управления DataGridView (отображение сетки данных) отображает информацию таблицы в виде строк и столбцов. Применим четыре объекта DataGridView для отображения таблицы Книги, таблицы Авторы, таблицы Издательства и таблицы КнгАвт базы данных Библиотека2. Эти управляющие элементы могут быть получены простым перетаскиванием на форму таблиц из окна Data Sources. 1. Из окна Data Sources нужно поочередно перетащить на соответствующую форму каждую из таблиц Книги, Авторы, Издательства и КнгАвт. В результате этих действий на каждой форме появится навигатор (панель в верхней части формы) и сетка данных. Например, вид формы Form1 должен соответствовать рис. 8. Если посмотреть на код каждой формы проекта, то можно увидеть, что система автоматически создала для каждой формы две подпрограммы (см. листинг 3). Листинг 3. Автоматически сгенерированный системой код Код формы Form1: Private Sub КнигиBindingNavigatorSaveItem_Click(ByVal _ sender As System.Object, ByVal e As System.EventArgs) _ Handles КнигиBindingNavigatorSaveItem.Click Me.Validate() Me.КнигиBindingSource.EndEdit() Me.TableAdapterManager.UpdateAll(Me.Библиотека2DataSet) End Sub Private Sub Form1_Load(ByVal sender As System.Object, _ 10 ByVal e As System.EventArgs) Handles MyBase.Load Me.КнигиTableAdapter.Fill( _ Me.Библиотека2DataSet.Книги) End Sub Код формы Form2: Private Sub АвторыBindingNavigatorSaveItem_Click(ByVal _ sender As System.Object, ByVal e As System.EventArgs) _ Handles АвторыBindingNavigatorSaveItem.Click Me.Validate() Me.АвторыBindingSource.EndEdit() Me.TableAdapterManager.UpdateAll(Me.Библиотека2DataSet) End Sub Private Sub Form2_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Me.АвторыTableAdapter.Fill( _ Me.Библиотека2DataSet.Авторы) End Sub Код формы Form3: Private Sub ИздательстваBindingNavigatorSaveItem_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles ИздательстваBindingNavigatorSaveItem.Click Me.Validate() Me.ИздательстваBindingSource.EndEdit() Me.TableAdapterManager.UpdateAll(Me.Библиотека2DataSet) End Sub Private Sub Form3_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Me.ИздательстваTableAdapter.Fill( _ Me.Библиотека2DataSet.Издательства) End Sub Код формы Form4: Private Sub КнгАвтBindingNavigatorSaveItem_Click(ByVal _ sender As System.Object, ByVal e As System.EventArgs) _ Handles КнгАвтBindingNavigatorSaveItem.Click Me.Validate() Me.КнгАвтBindingSource.EndEdit() Me.TableAdapterManager.UpdateAll( _ Me.Библиотека2DataSet) End Sub Private Sub Form4_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Me.КнгАвтTableAdapter.Fill( _ Me.Библиотека2DataSet.КнгАвт) End Sub 11 Рис. 8. Размещение объектов на форме Form1 Поясним назначение этого сгенерированного системой кода на примере кода формы Form1. Подпрограмма КнигиBindingNavigatorSaveItem_Click отвечает за сохранение данных после их изменения в отображаемой таблице КнигиDataGridView. Сохранение данных выполняется за три шага: 1. Проверка корректности введенных данных: Validate(). 2. Сохранение изменений: EndEdit(). 3. Обновление записей в базе данных: Me.TableAdapterManager.UpdateAll(Me.БиблиотекаDataSet). Подпрограмма Form1_Load при загрузке формы Form1 обеспечивает заполнение таблицы Книги набора данных БиблиотекаDataSet (объекта Библиотека2DataSet.Книги) данными из базы данных (применяется метод Fill). Теперь, наконец, если запустить проект, то можно убедиться, что можно видеть содержащуюся в базе данных информацию. Этот проект нам нужен только для экспериментов с запросами. Его не предполагается применять для изменения информации в базе данных. Это позволяет не тратить время на повышение удобств работы с управляющими элементами DataGridView, связанными с необходимостью изменения данных. 15. Построение запросов LINQ к DataSet 1. Для работы с запросами добавьте на форму Form5 кнопку Button2 и текстовое поле TextBox1, в котором будут отображаться результаты запроса. 2. Чтобы при при визуализации формы Form5 происходило обновление всех таблиц набора данных Библиотека2DataSet, в код кнопки Button4 на форме Form1 12 следует добавить инструкции, выполняющие загрузку информации из базы данных во все таблицы набора данных. С учетом этого код подпрограммы Button4_Click формы Form1 должен соответствовать листингу 4. Листинг 4. Код подпрограммы Button4_Click Private Sub Button4_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles Button4.Click Form5.Show() Me.Hide() Form2.АвторыTableAdapter.Fill( _ Form2.Библиотека2DataSet.Авторы) Form3.ИздательстваTableAdapter.Fill( _ Form3.Библиотека2DataSet.Издательства) Form4.КнгАвтTableAdapter.Fill( _ Form4.Библиотека2DataSet.КнгАвт) Form5.Show() Me.Hide() End Sub Предусмотренная в этой подпрограмме загрузка из базы данных таблиц Авторы, Издательства и КнгАвт набора данных необходима, так как после запуска проекта загружена тлько форма Form1. В набор данных Библиотека2DataSet из базы данных загружена только таблица Библиотека2DataSet.Книги. Остальные три формы еще не загружались, следовательно, данные из базы данных в таблицы набора данных Библиотека2DataSet.Авторы, Библиотека2DataSet.Издательства и Библиотека2DataSet.КнгАвт еще не загружены. Но они необходимы для выполнения запросов к Библиотека2DataSet на форме Form5. После выполнения этих подготовительных действий можно проверить работу любой подпрограммы, выполняющих запрос. 3. Пусть требуется отобразить список всех книг библиотечного фонда, включающий несколько полей одной и той же таблицы, например, включающий поля ГодИзд, Цена и Название таблицы Книги. Свяжите с кнопкой Button2 на форме Form5 код, показанный на листинге 5. Листинг 5. Код подпрограммы Button2_Click Private Sub Button2_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles Button2.Click Dim knigi = Form1.Библиотека2DataSet.Tables( _ "Книги") Dim Запрос1 = From kn In knigi.AsEnumerable _ Select kn!Название, kn!ГодИзд, _ kn!Цена TextBox1.Clear() For Each r In Запрос1 TextBox1.AppendText(vbTab & r.ГодИзд & _ vbTab & r.Цена & vbTab & _ r.Название & vbCrLf) Next End Sub Применение метода AsEnumerable позволяет выполнять запросы к таблицам набора данных точно так же как и к объектам с интерфейсом IEnumerable. 13 В результате выполнения этой подпрограммы в текстовом поле TextBox1 будет отображен требуемый список (см. табл. 2). Получение всех данных из нескольких полей одной и той же таблицы Таблица 2 2008 2008 2002 2008 2004 2006 2003 2004 2002 2003 2005 2002 2003 2003 2008 2006 436 120 250 400 300 1200 600 150 200 300 250 250 450 180 520 150 Самоучитель Visual Basic 2008 Основы программирования на Visual Basic и VBA в Excel Эффективная работа: Visual Basic.NET Visual Basic.NET 2008 Microsoft Visual Basic.NET. Шаг за шагом Visual Basic 2005 в учебе, науке и технике Самоучитель по анимации и мультипликации в Visual Basic.NET 2003 Visual Basic.NET Visual Basic.NET: разработка приложений Visual Basic.NET. Экспресс курс Занимательное программирование на Visual Basic.NET Visual Basic.NET. Справочник Обработка баз данных на Visual Basic.NET Объектно-ориентированное программирование в Visual Basic.NET Visual Basic 2005 и платформа .NET 2.0 Visual Basic 2005 для "ЧАЙНИКОВ" Если выше перед предложением Select вставить строку Where kn!ГодИзд = 2008, то в списке остануться только книги, изданные в 2008 г. Проверьте это. 4. В запрос можно включать данные из разных таблиц. Предположим, что необходимо получить список книг фонда библиотеки, изданных в 2008 году, включающий фамилию автора и название книги. Добавьте на форме Form5 кнопку Button3. Требуемый запрос выполнит подпрограмма Button3_Click, код которой содержит листинг 6. Листинг 6. Код подпрограммы Button3_Click Private Sub Button3_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles Button3.Click Dim knigi = _ Form1.Библиотека2DataSet.Tables("Книги") Dim avtory = _ Form2.Библиотека2DataSet.Tables("Авторы") Dim kngavt = _ Form4.Библиотека2DataSet.Tables("КнгАвт") Dim Запрос2 = From kn In knigi.AsEnumerable, _ ka In kngavt.AsEnumerable, _ avt In avtory.AsEnumerable _ Where kn!ГодИзд = 2008 And _ (kn!Код = ka!КодКниги And _ avt!Код = ka!КодАвтора) _ Select Фамилия = avt!Фамилия, _ Название = kn!Название TextBox1.Clear() For Each r In Запрос2 TextBox1.AppendText(r.Фамилия & vbTab & _ r.Название & vbTab & vbCrLf) 14 Next End Sub Результат работы этой подпрограммы показан в табл. 3. Получение данных из полей разных таблиц Шевякова Дукин Степанов Гарбер Глушаков Клевцов Троелсен Таблица 3 Самоучитель Visual Basic 2008 Самоучитель Visual Basic 2008 Самоучитель Visual Basic 2008 Основы программирования на Visual Basic и VBA в Excel Visual Basic.NET 2008 Visual Basic.NET 2008 Visual Basic 2005 и платформа .NET 2.0 Здесь мы видим, что если у книги не один, а несколько авторов, то название книги повторяется для каждого автора. 5. Следующий запрос, который мы рассмотрим покажет, как можно выполнить группирование данных. Пусть необходимо получить список всех книг библиотеки сгруппированных по годам издания. Добавьте на форме Form5 кнопку Button4. Требуемый запрос выполнит подпрограмма Button4_Click, код которой содержит листинг 7. Листинг 7. Код подпрограммы Button4_Click Private Sub Button4_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles Button4.Click Dim knigi = _ Form1.Библиотека2DataSet.Tables("Книги") Dim Запрос3 = From kn In knigi.AsEnumerable _ Order By kn!ГодИзд Descending _ Select Название = kn!Название, _ ГодИзд = kn!ГодИзд TextBox1.Clear() For Each r In Запрос3 TextBox1.AppendText(r.ГодИзд & vbTab & _ r.Название & vbCrLf) Next End Sub В этой подпрограмме задана сортировка списка групп (поле ГодИзд) по убыванию. Пример работы этой подпрограммы приведен в табл. 3. 6. Подготовьте запрос для вычисления стоимости библиотечного фонда. Добавьте на форме Form5 кнопку Button5. Требуемый запрос выполнит подпрограмма Button5_Click, код которой содержит листинг 8. Листинг 8. Код подпрограммы Button4_Click Private Sub Button5_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button5.Click Dim knigi = Form1.Библиотека2DataSet.Tables( _ "Книги") Dim Запрос4 = From kn In knigi.AsEnumerable _ Select CDec(kn!Цена * kn!Количество) TextBox1.AppendText("Содержание запроса:" & vbCrLf) TextBox1.Clear() For Each v In Запрос4 TextBox1.AppendText(vbTab & v & vbCrLf) Next 15 Dim r = Aggregate v In Запрос4 Into Sum() TextBox1.AppendText("Итого: " & _ r & vbCrLf) End Sub Группирование данных 2008 2008 2008 2008 2006 2006 2005 2004 2004 2003 2003 2003 2003 2002 2002 2002 Таблица 3 Самоучитель Visual Basic 2008 Основы программирования на Visual Basic и VBA в Excel Visual Basic.NET 2008 Visual Basic 2005 и платформа .NET 2.0 Visual Basic 2005 в учебе, науке и технике Visual Basic 2005 для "ЧАЙНИКОВ" Занимательное программирование на Visual Basic.NET Microsoft Visual Basic.NET. Шаг за шагом Visual Basic.NET Самоучитель по анимации и мультипликации в Visual Basic.NET 2003 Visual Basic.NET. Экспресс курс Обработка баз данных на Visual Basic.NET Объектно-ориентированное программирование в Visual Basic.NET Эффективная работа: Visual Basic.NET Visual Basic.NET: разработка приложений Visual Basic.NET. Справочник Аргумент статистической функции Sum() должен иметь любой числовой тип. Поэтому в разделе Celect применена функция преобразования к типу Decimal. Результат работы подпрограммы Button5_Click показан в табл. 4. Вычисление стоимости библиотечного фонда Таблица 4 4360 360 750 2000 1500 2400 1200 1500 1000 3000 750 1250 900 540 2600 750 Итого: 24860 7. Подготовьте запрос для определения общего количества экземпляров книг библиотечного фонда. Для этого необходимо добавить на форме Form5 кнопку Button6. Составьте код подпрограммы подпрограмма Button6_Click. Проверьте ее работу. 9. Попробуйте ответить на вопросы для контроля. 10. Покажите работу Вашего проекта преподавателю. 11. Удалите свою рабочую папку на диске d. 16 16. Воросы для контроля 1. К каким источникам данных можно применять запрос LINQ? 2. В каком разделе запроса задается источник данных? 3. Когда в запросе применяется раздел Where? 4. Перечислите статистические операции, доступные в LINQ. 5. В каком разделе задается сортировка элементов запроса? 6. Какова роль в запросе зарезервированного слова Distinct? 7. Что такое группировка?