Transcript LINQ basics
Высокоуровневые методы информатики и программирования Лекция 16 Встроенный язык запросов
План работы
• Введение в язык LINQ • LINQ to Object • Интерфейс IEnumerable
Постановка задачи
• В программе часто требуется выполнять выборки объектов из различных источников данных – находить элементы, которые удовлетворяют некоторым условиям, – Упорядочивать элементы, – формировать на новые объекты используя существующие.
• Существует много типов источников данных, которые хранят множества объектов: – массивы; – коллекции (нетипизированные и типизированные); – XML документы; – базы данных.
• Оказалось, что можно единообразно решать эти задачи для всех этих типов источников данных.
• С этой целью в языке C# был разработан новый язык: Language INtegrated Query - LINQ .
LINQ - Language INtegrated Query
• Новая возможность языка C# 3.0; • Запросы к источникам данных являются частью языка C#; • Стандартные операции запросов Standard Query Operators API; • Единый язык запросов к коллекциям в памяти, XML документам и базам данных.
LINQ позволяет
• создавать и выполнять единообразные запросы (query expressions) для работы с – любыми объектами, которые реализуют интерфейс IEnumerable
Технологии LINQ
Разновидности LINQ
• LINQ to Objects работы с БД).
– для выполнения запросов к структурам данных в оперативной памяти (System.Linq).
• LINQ to SQL (DLinq) реляционным БД. Выполняет трансляцию LINQ запросов к объектной модели в запросы SQL и посылает их к базе данных для выполнения. После возврата результатов от БД, LINQ to SQL транслирует их назад в объекты, с которыми может работать. • LINQ to Entities – помощью описания соответствия между классами программы и логической моделью баз данных.
• LINQ to DataSet – БД в оперативной памяти – DataSet (отсоединенной режим • LINQ to XML (XLinq) документам. Дает возможность искать коллекции элементов и атрибутов. Аналогичен XPath и XQuery. (System.Xml.Linq) –для выполнения запросов к способ выполнения запросов к БД с для выполнения запросов к выборке из – для выполнения запросов к XML
Преимущества LINQ
• Единообразный способ запроса к данным. • Единый синтаксис для изучения и запоминания.
• Строго типизированные запросы - ошибки определяются уже при компиляции.
• Работает подсказка IntelliSense в Visual Studio.
Технология LINQ to Objects
• Для выполнения запросов к структурам данных в оперативной памяти. Можно делать запросы к любому типу данных, который поддерживает интерфейс IEnumerable
Интерфейс IEnumerable
• Все обобщенные коллекции поддерживают этот интерфейс.
• Большинство Standard Query Operators являются расширяющими методами в статическом классе System.Linq.Enumerable
с типом IEnumerable
и содержат первый параметр • Для получения доступа к Standard Query Operators необходимо добавить namespace System.Linq
( содержится в DLL System.Core.dll, подключается автоматически).
• Последовательность это любая коллекция, которая поддерживает данный интерфейс.
Общий вид LINQ запроса
var < результат> = from коллекции> in < < объект коллекция> where < условие> orderby < ключ> select < объект резутьтата>;
Операции LINQ запроса
• Для записи запросов можно использовать следующие ключевые слова.
Ключевые слова
from, in where select join, on, equals, into orderby, ascending, descending group, by
Для чего используется
для определения основных элементов любого LINQ выражения, для извлечения подмножества данных из контейнера (источника данных) для задания условия на извлекаемые данные для описания получаемого результата выборки.
для объединения (joins) на основе заданных значений из разных источников.
для упорядочения (сортировки) получаемых данных результаты в порядке возрастания (ascending) или убывания (descending) позволяет выдавать данные по подгруппам с заданным значением.
Грамматика выражении запросов (Query Expressions)
При составлении выражений запросов
необходимо
правилам: 1.
2.
3.
4.
5.
следовать следующим Запрос должен начинаться с ключевого слова
from
.
Основная часть запроса может включать несколько ключевых слов
from
или
where
. • Слово • Слово
from
это генератор, который объявляет одну или более переменную перечисления, которые пробегают по элементам последовательности или объединения нескольких последовательностей.
where
фильтрует элементы последовательности или объединения нескольких последовательностей в результирующую последовательность. Затем может идти слово
orderby
, которое содержит одно или несколько полей сортировки с возможностью указания направления сортировки (по увеличению или уменьшению значения поля).
Затем должны следовать слова
select
или
group
.
В конце запроса может быть продолжение. В продолжении м.б. 1.
2.
3.
слово
into
(направляет результаты запроса в воображаемую последовательность вывода, которое работает как слово
from
запроса, начинающейся со слов в пункте 2), для части или несколько слов
join
, или другая повторяющаяся последовательность этих пронумерованных пунктов, начиная со слов в пункте № 2.
Методы выборки LINQ
Для результатов выборки можно выполнить различные методы: Aggregate Conversion Average Count Max Min Sum ToArray ToDictionary ToList ToLookup ToSequence Ordering Partitioning OrderBy ThenBy Descending Reverse Skip SkipWhile Take TakeWhile Sets Concat Distinct Except Intersect Union и многие другие
Пример с массивом
Задача: выбрать из целочисленного массива все числа меньше 5 и упорядочить их.
Свой алгоритм C помощью LINQ int[] arr = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int[] arr1 = new int[10]; int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; { int kol = 0; for (int i = 0; i < arr.Length; i++) } if (arr[i] < 5) { arr1[kol] = arr[i]; kol++; } Array.Sort(arr1,0,kol);
var lowNums = from n in numbers where n < 5 orderby n select n;
Console.WriteLine
(“LINQ: Numbers < 5:"); foreach (var x in lowNums) { Console.WriteLine(x); } Console.WriteLine("Simple: Numbers < 5:"); for (int i=0;i • Запрос к массиву int[ ] numbers = { 10, 20, 30, 40, 1, 2, 3, 8 }; // Only print items less than 10. IEnumerable var subset = from i in numbers where i < 10 orderby i descending select i; // ...and here. foreach (var i in subset) Console.WriteLine("Item: {0} ", i); } { public class Customer public string Name; public Address Address; public string Phone; public List public string Name; Customer c = GetCustomer( …); var x = new { Name = c.Name, Phone = c.Phone }; } Customer c = GetCustomer( …); var x = new { c.Name, c.Phone }; Создание анонимного типа с инициализацией } class Contact { … }; List • Результат выборки можно преобразовать в коллекции с помощью методов – ToArray • Например: int[] numbers = { 10, 20, 30, 40, 1, 2, 3, 8 }; // Получить результат выборки в виде массива int[]. int[] subsetAsIntArray = (from i in numbers where i < 10 select i).ToArray List var numbers = new int[] { 1, 4, 9, 16, 25, 36 }; List } public class car { // конструктор public car(string make,int year) { Make=make; Year=year; } // свойства public int Year { get; set ;} public string Make { get; set;} // Создаем массив объектов car. { car[ ] arrayOfCars = new car[6] new car("Ford",1992), new car("Fiat",1988), new car("Buick",1932), new car("Ford",1932), }; new car("Dodge",1999), new car("Honda",1977) var cars = from cr in arrayOfCars where (cr.Year<1960) select cr; } { foreach (var с in cars) Console.WriteLine("{0} – {1}", c.Make,c.Year); • { Пример простого класса: class Car public string Nomer = string.Empty; public string Color = string.Empty; public int Speed; public string Make = string.Empty; } • { Создание коллекции static void Main(string[] args) // Создаем обобщенную коллекцию объектов Car – List List // Create a query expression. var fastCars = from c in myCars where c.Speed > 200 select c; foreach (var car in fastCars) Console.WriteLine("{0} ездит слишком быстро!", car.Nomer); • Общий вид запроса var result = from item in container select item; var allCars = from c in myCars select c; var nomers = from c in myCars select c.Nomer; var makes = (from c in myCars select c.Make).Distinct result = from item in container where Boolean expression select item; var onlyBMWs = from c in myCars where c.Make == "BMW" select c; var onlyFastBMWs = from c in myCars where c.Make == "BMW" && c.Speed >= 100 select c; Создание объектов нового типа var result = from item in container select new {…} var makesColors = from c in myCars select new {c.Make, c.Color}; Сортировка результатов var result = from item in container orderby value select item; ascending/descending var subset = from c in myCars orderby c.Nomer select c; var subset = from c in myCars where c.Speed > 55 orderby c.PetName descending select c; • Преобразование в другие типы Reverse<>(), ToArray<>(), ToList<>(), и др. • Извлечени некоторых элементов Distinct<>(), Union<>(), Intersect<>() и др. • Выполнение операций над элементами - Count<>(), Sum<>(), Min<>(), Max<>() и др. // Определяем количество элементов выборки int numb = (from g in currentVideoGames where g.Length > 6 orderby g select g).Count } { static void GetDiff() List .Except (from c2 in yourCars select c2); Console.WriteLine("Here is what you don't have, but I do:"); foreach (string s in carDiff) Console.WriteLine(s); // Prints Yugo. } { public class Customer public string CustomerID { get; set; } public string Name { get; set; } } public string City { get; set; } { public override string ToString() return CustomerID + "\t" + City; { public class Order public int OrderID { get ; set;} public int ItemID { get; set; } public string CustomerID { get; set; } public DateTime OrderDate { { get; set; } public override string ToString() return string.Format("OrderID:{0} \r\nOrderName: } {1} OrderDate: {2}", OrderID, OrderName, OrderDate); } } { public class Item public int ItemID {get;set;} public string ItemName {get;set;} public string Category { get; set; } public decimal UnitPrice {get; set; } public int UnitsInStock } { {get; set; } public override string ToString() return string.Format("ItemID : {0} \r\nItemName: {1} \r\n " + "Category: {2} \r\nUnitPrice: {3} \r\nUnitsInStock: {4}", ItemID, ItemName, Category, UnitPrice, UnitsInStock); { List } { List List // получение всех потребителей живущих в Лондоне var results = from c in cust where c.City == " Лондон" select c; foreach (var c in results1) Console.WriteLine(c); // получение всех потребителей упорядоченных по названию города и имени var results = from с in cust orderby c.City, c.Name select new {c.City, c.Name} // получение всех товаров дороже 10 и упорядочение по увеличению цены var SelOrder = (from a in itemList where (a.UnitPrice > 10M) orderby a.UnitPrice select a); foreach (var obj in SelOrder) Console.WriteLine("ItemName = {0}, UnitPrice = {1}", obj.ItemName, obj.UnitPrice); // получение всех товаров дороже 10 и упорядочение по уменьшению цены SelOrder = (from a in itemList where (a.UnitPrice > 10M) orderby a.UnitPrice descending select a); foreach (var obj in SelOrder) Console.WriteLine("ItemName = {0}, UnitPrice = {1}", obj.ItemName, obj.UnitPrice); // получение двух товаров дороже 10 и упорядочение по уменьшению цены, // без самого дорогого товара var SelOrder2 = (from a in itemList where (a.UnitPrice > 10M) orderby a.UnitPrice descending select a).Skip(1).Take(2); foreach (var obj in SelOrder2) Console.WriteLine("ItemName = {0}, Price = {1}", obj.ItemName,obj.UnitPrice); var itemOrders = from i in itemList join o in orderList on i.ItemID equals o.ItemID select new { i.ItemName, CustomerID} • Выборка не формируется до тех пор, пока она не будет использоваться Пример: int[ ] numbers = {10,20,30,40,1,2,3,8 }; // описываем выражения для получаем числа // меньше чем 10. var subset = from i in numbers where i < 10 select i; // выражение LINQ выполняется здесь! foreach (var i in subset) Console.WriteLine("{0} < 10", i); Console.WriteLine(); // Меняем некоторые данные в массиве. numbers[0] = 4; // Опять оцениваем выражение. foreach (var j in subset) Console.WriteLine("{0} < 10", j); Соответствие языков LINQ и SQL • • Языки LINQ и SQL имеют много общего Язык LINQ (интегрированный язык) var query = from element in collection [, from element2 in collection2] where condition orderby orderExpression [ ascending | descending ] [, orderExpression2 ...] • select [alias = ]columnExpression[,[alias2 = ]columnExpression2] Язык SQL (язык реляционныхбаз данных) SELECT [Element.ColumnExpression[, Element2.ColumnExpression2] FROM Collection AS Element[, Collection2 AS Element2] WHERE Condition ORDER BY OrderExpression [ASCENDING|DESCENDING][, OrderExpression2 ...] • SQL запрос к БД SELECT * from Books WHERE QuatityInStock > 50 AND Price > 50.00 • LINQ запрос к коллекции объектов var result = from b in Books b.QuatityInStock > 50 && where Price > 50.00 select b; using System; using System.Linq; using System.Data.Linq; using nwind; // // создаем объект для доступа к БД Northwind Northwind db = new Northwind(@"Data Source=.\SQLEXPRESS;Initial Catalog=Northwind"); // LINQ запрос к таблице Customer в объекте db var custs = from c in db.Customers where c.City == "Rio de Janeiro" select c; // вывод полученных результатов foreach (var cust in custs) Console.WriteLine("{0}", cust.CompanyName);Пример
Анонимные типы
LINQ стиль программирования
Преобразование выборки в коллекции
Пример преобразования
Пример с объектами класса
LINQ и обобщенные коллекции
Запрос к обобщенной коллекции
Построение запросов
Преобразование над IEnumerable
Определение количества элементов
Определение различий
Классы Customer и Order
Класс Item
Коллекция заказчиков
Коллекция товаров itemList
Коллекция заказов orderList
Простые запросы
Связывание источников данных и создание нового класса
Отложенное выполнение
Примеры запросов SQL и LINQ
Простой LINQ запрос к базе данных SQL Server