1 / 39

Высокоуровневые методы информатики и программирования Лекция 16 Встроенный язык запросов

Высокоуровневые методы информатики и программирования Лекция 16 Встроенный язык запросов. План работы. Введение в язык LINQ LINQ to Object Интерфейс IEnumerable <T> Примеры в Visual Studio Отличие от SQL. Постановка задачи.

nasya
Download Presentation

Высокоуровневые методы информатики и программирования Лекция 16 Встроенный язык запросов

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Высокоуровневые методы информатики и программированияЛекция 16Встроенный язык запросов

  2. План работы • Введение в язык LINQ • LINQ to Object • Интерфейс IEnumerable<T> • Примеры в Visual Studio • Отличие от SQL

  3. Постановка задачи • В программе часто требуется выполнять выборки объектов из различных источников данных • находить элементы, которые удовлетворяют некоторым условиям, • Упорядочивать элементы, • формировать на новые объекты используя существующие. • Существует много типов источников данных, которые хранят множества объектов: • массивы; • коллекции (нетипизированные и типизированные); • XML документы; • базы данных. • Оказалось, что можно единообразно решать эти задачи для всех этих типов источников данных. • С этой целью в языке C# был разработан новый язык: Language INtegratedQuery - LINQ.

  4. LINQ - Language INtegrated Query • Новая возможность языка C# 3.0; • Запросы к источникам данных являются частью языка C#; • Стандартные операции запросов - StandardQueryOperators API; • Единый язык запросов к коллекциям в памяти, XML документам и базам данных.

  5. LINQ позволяет • создавать и выполнять единообразные запросы (query expressions) для работы с • любыми объектами, которые реализуют интерфейсIEnumerable<T> (непосредственно или через расширяющие методы); • реляционными базами данных; • объектами DataSets (которые хранят данные из БД); • XML документами.

  6. Технологии LINQ

  7. Разновидности LINQ • LINQ toObjects– для выполнения запросов к структурам данных в оперативной памяти (System.Linq). • LINQ to SQL (DLinq) –для выполнения запросов к реляционным БД. Выполняет трансляцию LINQ запросов к объектной модели в запросы SQL и посылает их к базе данных для выполнения. После возврата результатов от БД, LINQ to SQL транслирует их назад в объекты, с которыми может работать. • LINQ toEntities – способ выполнения запросов к БД с помощью описания соответствия между классами программы и логической моделью баз данных. • LINQ toDataSet – для выполнения запросов к выборке из БД в оперативной памяти – DataSet (отсоединенной режим работы с БД). • LINQ to XML (XLinq) – для выполнения запросов к XML документам. Дает возможность искать коллекции элементов и атрибутов. Аналогичен XPath и XQuery. (System.Xml.Linq)

  8. Преимущества LINQ • Единообразный способ запроса к данным. • Единый синтаксис для изучения и запоминания. • Строго типизированные запросы - ошибки определяются уже при компиляции. • Работает подсказка IntelliSense в Visual Studio.

  9. Технология LINQ toObjects • Для выполнения запросов к структурам данных в оперативной памяти. Можно делать запросы к любому типу данных, который поддерживает интерфейс IEnumerable<T> (C#) • Пространство имен System.Linq.

  10. Интерфейс IEnumerable<T> • Все обобщенные коллекции поддерживают этот интерфейс. • Большинство StandardQueryOperators являются расширяющими методами в статическом классе System.Linq.Enumerable и содержат первый параметр с типом IEnumerable<T>. • Для получения доступа к StandardQueryOperators необходимо добавить namespace System.Linq (содержится в DLL System.Core.dll, подключается автоматически). • Последовательность это любая коллекция, которая поддерживает данный интерфейс.

  11. Общий вид LINQ запроса var <результат> = from <объектколлекции>in <коллекция> where <условие> orderby <ключ> select <объект резутьтата>;

  12. Операции LINQ запроса • Для записи запросов можно использовать следующие ключевые слова.

  13. Грамматика выражении запросов (Query Expressions) При составлении выражений запросов необходимо следовать следующим правилам: • Запрос должен начинаться с ключевого слова from. • Основная часть запроса может включать несколько ключевых слов from или where. • Слово from это генератор, который объявляет одну или более переменную перечисления, которые пробегают по элементам последовательности или объединения нескольких последовательностей. • Слово where фильтрует элементы последовательности или объединения нескольких последовательностей в результирующую последовательность. • Затем может идти слово orderby, которое содержит одно или несколько полей сортировки с возможностью указания направления сортировки (по увеличению или уменьшению значения поля). • Затем должны следовать слова select или group. • В конце запроса может быть продолжение. В продолжении м.б. • слово into(направляет результаты запроса в воображаемую последовательность вывода, которое работает как слово from для части запроса, начинающейся со слов в пункте 2), • или несколько слов join, • или другая повторяющаяся последовательность этих пронумерованных пунктов, начиная со слов в пункте № 2.

  14. Методы выборки LINQ Для результатов выборки можно выполнить различные методы: и многие другие

  15. Пример с массивом Задача: выбрать из целочисленного массива все числа меньше 5 и упорядочить их. int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; varlowNums = from n in numberswhere n < 5 orderby n select n; Console.WriteLine(“LINQ: Numbers < 5:"); foreach (var x in lowNums) {  Console.WriteLine(x); } Свой алгоритм C помощью LINQ int[] arr = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int[] arr1 = new int[10]; intkol = 0; for (int i = 0; i < arr.Length; i++) { if (arr[i] < 5){ arr1[kol] = arr[i]; kol++; } } Array.Sort(arr1,0,kol); Console.WriteLine("Simple: Numbers < 5:"); for (int i=0;i<kol; i++) { Console.WriteLine(arr1 [i]); }

  16. Пример • Запрос к массиву int[] numbers = { 10, 20, 30, 40, 1, 2, 3, 8 }; // Only print items less than 10. IEnumerable<int> subset = from i in numbers where i < 10 orderbyi descending select i; foreach (inti in subset) Console.WriteLine("Item: {0}", i); • Использование var int[] numbers = {10, 20, 30, 40, 1, 2, 3, 8}; // Use implicit typing here... var subset = from i in numbers where i < 10 orderbyi descending select i; // ...and here. foreach (vari in subset) Console.WriteLine("Item: {0} ", i);

  17. Анонимные типы public class Customer { public string Name; public Address Address; public string Phone; public List<Order> Orders; … } public class Contact { public string Name; public string Phone; } class ??? { public string Name; public string Phone; } Customer c = GetCustomer(…); Contact x = new Contact { Name = c.Name, Phone = c.Phone }; Customer c = GetCustomer(…); var x = new { Name = c.Name, Phone = c.Phone }; Создание анонимного типа с инициализацией Customer c = GetCustomer(…); var x = new { c.Name, c.Phone };

  18. LINQ стиль программирования class Contact { … }; List<Contact> contacts = new List<Contacts>(); foreach(Customer c in customers) { if(c.State == “WA”) { Contact ct = new Contact(); ct.Name = c.Name; ct.Phone = c.Phone; contacts.Add(ct); } } var contacts = from c in customers where c.State == "WA" select new { c.Name, c.Phone };

  19. Преобразование выборки в коллекции • Результат выборки можно преобразовать в коллекции с помощью методов • ToArray<T>(), • ToDictionary<TSource,TKey>(), • ToList<T>(). • Например: int[] numbers = { 10, 20, 30, 40, 1, 2, 3, 8 }; // Получить результат выборки в виде массива int[]. int[] subsetAsIntArray = (from i in numbers where i < 10 select i).ToArray<int>(); // Получить результат выборки в видеколлекции List<int>. List<int> subsetAsListOfInts = (from i in numbers where i < 10 select i).ToList<int>();

  20. Пример преобразования var numbers = new int[] { 1, 4, 9, 16, 25, 36 }; List<int> numQuery2 = (from num in numbers where (num % 2) == 0 select num).ToList();// or like this: // numQuery3 is still an int[] var numQuery3 = (from num in numbers where (num % 2) == 0 select num).ToArray();

  21. Пример с объектами класса // Создаем массив объектов 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); } public class car { // конструктор public car(string make,int year) { Make=make; Year=year; } // свойства public int Year { get;set ;} public string Make { get;set;} }

  22. LINQ и обобщенные коллекции • Пример простого класса: 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<Car> List<Car> myCars = new List<Car>() { new Car{Nomer = "в562ва", Color = "Silver", Speed = 160, Make = "BMW"}, new Car{Nomer = "p123то", Color = "Tan", Speed = 140, Make = "BMW"}, new Car{Nomer = "c345ке", Color = "Black", Speed = 220, Make = "VW"}, new Car{Nomer = "в654нс", Color = "Rust", Speed = 180, Make = "Yugo"}, new Car{Nomer = "с162ми", Color = "White", Speed = 250, Make = "Ford"} }; }

  23. Запрос к обобщенной коллекции // 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);

  24. Построение запросов • Общий вид запроса varresult = from item in container select item; varallCars = from c in myCars select c; varnomers = from c in myCars select c.Nomer; var makes = (from c in myCars select c.Make).Distinct<string>(); • Запрос с условием varresult = from item in container where Boolean expression select item; varonlyBMWs = from c in myCars where c.Make == "BMW" select c; varonlyFastBMWs = from c in myCars where c.Make == "BMW" && c.Speed >= 100 select c; • Создание объектов нового типа varresult = from item in container select new {…} varmakesColors = from c in myCars select new {c.Make, c.Color}; • Сортировка результатов varresult = from item in container orderby valueascending/descending select item; var subset = from c in myCarsorderbyc.Nomer select c; var subset = from c in myCars where c.Speed > 55 orderbyc.PetName descending select c;

  25. Преобразование над IEnumerable<T> • Преобразование в другие типы -Reverse<>(), ToArray<>(), ToList<>(), и др. • Извлечени некоторых элементов - Distinct<>(), Union<>(), Intersect<>() и др. • Выполнение операций над элементами - Count<>(), Sum<>(), Min<>(), Max<>()и др.

  26. Определение количества элементов // Определяем количество элементов выборки int numb = (from g in currentVideoGames where g.Length > 6orderby gselect g).Count<string>();

  27. Определение различий static void GetDiff() { List<string> myCars = new List<String> { "Yugo", "Aztec", "BMW"}; List<string> yourCars = new List<String> { "BMW", "Saab", "Aztec" }; varcarDiff =(from c in myCars select c) .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. }

  28. Классы Customer и Order public class Order { public intOrderID { get ; set;} public intItemID { get; set; } public string CustomerID { get; set; } public DateTimeOrderDate { get; set; } public override string ToString() { return string.Format("OrderID:{0} \r\nOrderName: {1} OrderDate: {2}", OrderID, OrderName, OrderDate); } } 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; } }

  29. Класс Item public class Item { public intItemID {get;set;} public string ItemName {get;set;} public string Category { get; set; } public decimal UnitPrice {get; set; } public intUnitsInStock {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); } }

  30. Коллекция заказчиков List<Customer>cust = new List<Customer> { new Customer { CustomerID = "ALFKI", City = "Берлин", Name = "Франс Майер"}, new Customer { CustomerID = "BONAP", City = "Париж", Name = "Поль Франсе" }, new Customer { CustomerID = "CONSH", City = "Лондон", Name = "Джон Кенеди"}, new Customer { CustomerID = "EASTC", City = "Лондон", Name = "Иван Петров" }, new Customer { CustomerID = "FRANS", City = "Торонто", Name = "Петр Сидоров" }, new Customer { CustomerID = "LONEP", City = "Мюнхен", Name = "Борис Байер" }, new Customer { CustomerID = "NORTS", City = "Лондон", Name = "ЕленаГрин" }, new Customer { CustomerID = "THEBI", City = "Мюнхен", Name = "Фриц Гендер" } };

  31. Коллекция товаров itemList List<Item> itemList = new List<Item> { new Item { ItemID = 1, ItemName = "Энциклопедия", Category="Знание", UnitPrice = 55.99M, UnitsInStock = 39 }, new Item { ItemID = 2, ItemName = "Тренажер", Category="Спорт", UnitPrice = 75.00M, UnitsInStock = 17 }, new Item { ItemID = 3, ItemName = "Кородка для CD“, Category="Хранилище", UnitPrice = 4.99M, UnitsInStock = 13 }, new Item { ItemID = 4, ItemName = "Томатный кетчуп", Category="Продукты", UnitPrice = 0.56M, UnitsInStock = 53 }, new Item { ItemID = 5, ItemName = "Плеер IPod", Category="Развлечение", UnitPrice = 220.99M, UnitsInStock = 0 }, new Item { ItemID = 6, ItemName = "Война и мир CD", Category="Развлечение", UnitPrice = 7.99M,UnitsInStock = 120 }, new Item { ItemID = 7, ItemName = "Война миров DVD", Category="Развлечение", UnitPrice = 6.99M, UnitsInStock = 15 }, new Item { ItemID = 8, ItemName = "Клюквенный соус", Category=“Продукты", UnitPrice = 0.89M, UnitsInStock = 6 }, new Item { ItemID = 9, ItemName = "Диетический рис", Category="Продукты", UnitPrice = 13.00M, UnitsInStock = 29 }, new Item { ItemID = 10, ItemName = “Виноград", Category="Продукты", UnitPrice = 1.19M, UnitsInStock = 4 } }

  32. Коллекция заказов orderList List<Order> orderList = new List<Order> { new Order { OrderID = 1, ItemID = 2, CustomerID = "BONAP", OrderDate = DateTime.Now }, new Order { OrderID = 2, ItemID = 5, CustomerID= "FRANS", OrderDate = DateTime.Now }, new Order { OrderID = 3, ItemID = 7, CustomerID = "CONSH ", OrderDate = DateTime.Now }, new Order { OrderID = 4, ItemID = 9, CustomerID = "FRANS", OrderDate = DateTime.Now }, new Order { OrderID = 5, ItemID = 10, CustomerID = "FRANS", OrderDate = DateTime.Now } };

  33. Простые запросы // получение всех потребителей живущих в Лондоне var results = from c in cust where c.City == "Лондон" select c; foreach (var c in results1)Console.WriteLine(c); // получение всех потребителей упорядоченных по названию города и имени var results = from с in cust orderbyc.City, c.Name select new {c.City, c.Name}

  34. // получение всех товаров дороже 10 и упорядочение по увеличению цены varSelOrder = (from a in itemList where (a.UnitPrice > 10M) orderbya.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) orderbya.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) orderbya.UnitPrice descending select a).Skip(1).Take(2); foreach (var obj in SelOrder2) Console.WriteLine("ItemName = {0}, Price = {1}", obj.ItemName,obj.UnitPrice);

  35. Связывание источников данных и создание нового класса varitemOrders = from i in itemList join o inorderListoni.ItemIDequalso.ItemID select new { i.ItemName, CustomerID}

  36. Отложенное выполнение • Выборка не формируется до тех пор, пока она не будет использоваться Пример: 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);

  37. Соответствие языков 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 ...]

  38. Примеры запросов SQL и LINQ • SQL запрос к БД SELECT * from Books WHERE QuatityInStock > 50 AND Price > 50.00 • LINQ запрос к коллекции объектов var result = from b inBooks where b.QuatityInStock > 50 && Price > 50.00 select b;

  39. Простой LINQ запрос кбазе данных SQL Server 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 varcusts = from c in db.Customers where c.City == "Rio de Janeiro" select c; // вывод полученных результатов foreach (varcust in custs) Console.WriteLine("{0}", cust.CompanyName);

More Related