400 likes | 750 Views
LINQ. Eugeny L Yakimovitch http://desk.by/~ewger 2008. Источники. LINQ Home http://msdn.com/linq 101 LINQ Examples http://tinyurl.com/2rsmpd [VB] http://tinyurl.com/ymmyr7 [C#] LINQ Videos http://www.asp.net/learn/linq-videos Anders Hejlsberg on LINQ and Functional Programming
E N D
LINQ Eugeny L Yakimovitch http://desk.by/~ewger 2008
Источники • LINQ Homehttp://msdn.com/linq • 101 LINQ Exampleshttp://tinyurl.com/2rsmpd [VB] http://tinyurl.com/ymmyr7 [C#] • LINQ Videoshttp://www.asp.net/learn/linq-videos • Anders Hejlsberg on LINQ and Functional Programming • Chris Bowen“The Strongest LINQ”blogs.msdn.com/cbowen
Вместо вступления using System; usingSystem.Query; usingSystem.Collections.Generic; classapp { static void Main() { string[] names = { "Burke", "Connor", "Frank", "Everett", "Albert", "George", "Harris", "David" }; varexpr = froms in names wheres.Length == 5 orderbys selects.ToUpper(); foreach (string item inexpr) Console.WriteLine(item); } } BURKE DAVID FRANK
Синтаксический сахар • Синтаксический сахар (англ. syntactic sugar) — термин, обозначающий дополнения синтаксиса языка программирования, которые не добавляют новых возможностей, а делают использование языка более удобным для человека. «Синтаксический сахар» даёт программисту альтернативный путь, который является более практичным, являясь более кратким или похожим на распространенный способ записи. С формальной точки зрения ничего не меняется. • Конструкции, являющиеся «синтаксическим сахаром», могут легко транслироваться в конструкции основного синтаксиса. • Термин введен в обращения англ. информатиком Питером Ландином • (см. также http://www.wolfengagen.mephi.ru/people.htm)
Синтаксический сахар • int a = 1; int b; if (a > 0) b = 1; else b = 2; • int a = 1; int b = a > 0 ? 1 : 2;
Базовые элементы • LINQ зависит от нововведений представленных начиная с • C# 3.0 • VB 9 • Главные составляющие • Type Inferencing • Class and Collection Initializers • Anonymous Types • Extension Methods • Lambda Expressions • Query Expressions • Понимание этих основ =>LINQ • [Для более глубокого изучения см. также: Automatic Properties, Partial Methods, Implictly-Typed Arrays]
Вычисление типов • Модель типизации Хиндли — Милнера Механизм вывода типов основан на возможности автоматически полностью или частично выводить тип выражения, полученного при помощи вычисления некоторого выражения. Так как этот процесс систематически производится во время трансляции программы, транслятор часто может вывести тип переменной или функции без явного указания типов этих объектов.
Вычисление типов • Объявление переменной при помощи ключевого слова var • Компилятор вычисляет (определяет) тип на основании объявления Customer c = new Customer(“Bob”, “Smith”, 1234); var c = new Customer(“Bob”, “Smith”, 1234);
Вычисление типов • Только для локальных и проинициализированных переменных var c; // No var c = null; // No var c = default(string); // Yes public var DoThis(int x){} // No public void DoThis(var x){} // No
Инициализаторы объектов • Более краткая форма записи создания объектов • Происходит вызов соот. конструктора и инициализация указанных свойств (полей). Invoice i = new Invoice { CustomerId = 123, Name = “Test” }; Is equivalent to: Invoice I = new Invoice(); i.CustomerId = 123; i.Name = “Test”;
Анонимные типы • Инициализаторы объектов могут использоваться без указания типов • Результатом является анонимный тип • Класс генерируется неявно • Часто используется LINQ Invoice i = new Invoice { CustomerId = 123, Name = “SmithCo” }; var i2 = new Invoice { CustomerId = 123, Name = “SmithCo” }; var i3 = new {CustomerId = 123, Name = “SmithCo” }; var i4 = new {123, “SmithCo”};
Методы расширения • Расширяют («доопределяют») существующие типы • Добавляют методы без наследования, изменения или перекомпилирования исходных типов • Имеют доступ к public методам расширенного класса • Располагаются внутри статического класса; должны быть public и static • Необходимо использовать ключевое слово this перед параметром расширенного типа
Методы расширения • К наиболее распространенным методам расширения относятся LINQ методы (GroupBy, OrderBy, Average и др.) • Чтобы их использовать сначала нужно подключить область using System.Linq • Многие стандартные операторы запросов (LINQ методы расширения)
Методы расширения • class ExtensionMethods2 • { • static void Main() • { • int[] ints = { 10, 45, 15, 39, 21, 26 }; • var result = ints.OrderBy(g => g); • foreach (var i in result) • { • System.Console.Write(i + " "); • } • } • } • //Output: 10 15 21 26 39 45
Методы расширения • namespace ExtensionMethods • { • public static class MyExtensions • { • public static int WordCount(this String str) • { • return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length; • } • } • } • using ExtensionMethods; • string s = "Hello Extension Methods"; • int i = s.WordCount();
Лямбда выражения • Начиная с C# 2.0 стали доступны анонимные методы • При помощи делегатов можно встраивать код в другие методы; delegate void Display(string s); public class AnonyMoose { static void Main() { // Instatiate the delegate type using an anonymous method: Display d = delegate(string j) { System.Console.WriteLine(j); }; d(“Call delegate using the anonymous method"); } } КАК ЭТО МОЖНО УПРОСТИТЬ?
Лямбда выражения • Основаны на анонимных функциях • Имеют более лаконичный, функциональный синтаксис • Безопасная типизация • Принимают и передают функции в качестве формальных параметров для последующего исполнения
Лямбда выражения static void Main(string[] args) { Func<int, int> addOne = n => n + 1; Console.WriteLine(addOne(5)); // Print 6 Expression<Func<int, int>>addOneExpression = n => n + 1; var addOneFunc = addOneExpression.Compile(); Console.WriteLine(addOneFunc(5)); // Print 6 }
Лямбда выражения • Предикаты и проекции • Predicate • (p) => p.Gender == “F” • “Все люди, p, такие что их поле Gender есть F” • Projection • (p)=> p.Gender ? “F” : “Female” • “Каждого человека p,вычислить как строку “Female”,если поле Gender есть “F””
Язык запросов • Представляет собой SQL-подобный синтаксис • Компилируется в традиционный C# (при помощи методов расширения) fromitemName insrcExpr joinitemNameinsrcExpronkeyExpr equalskeyExpr (intoitemName)? let itemName =selExpr wherepredExpr orderby (keyExpr (ascending | descending)?)* selectselExpr groupselExprbykeyExpr intoitemName query-body
The LINQ Project <book> <title/> <author/> <year/> <price/> </book> Relational Objects XML .NET Language Integrated Query C# 3.0 Visual Basic 9.0 Others LINQ toObjects LINQ toDataSets LINQ toSQL LINQ toEntities LINQ toXML
LINQ to Objects <book> <title/> <author/> <year/> <price/> </book> Relational Objects XML .NET Language Integrated Query C# 3.0 Visual Basic 9.0 Others LINQ toObjects LINQ toDataSets LINQ toSQL LINQ toEntities LINQ toXML
using System; usingSystem.Query; usingSystem.Collections.Generic; classapp { static void Main() { string[] names = { "Allen", "Arthur", "Bennett" }; IEnumerable<string> ayes = names .Where(s => s[0] == 'A'); foreach (string item in ayes) Console.WriteLine(item); names[0] = "Bob"; foreach (string item in ayes) Console.WriteLine(item); } } Arthur LINQ to Objects Родной синтаксисзапросов для C# и VB IntelliSense Autocompletion Операторы запросов можно применить к любому потомку.NET коллекции (IEnumerable<T>) Select, Where, GroupBy, Join, etc. Ленивое или отложенное вычисление запросов Лямбда выражения using System; usingSystem.Query; usingSystem.Collections.Generic; classapp { static void Main() { string[] names = { "Burke", "Connor", "Frank", "Everett", "Albert", "George", "Harris", "David" }; IEnumerable<string> expr = from s in names wheres.Length == 5 orderby s selects.ToUpper(); foreach (string item inexpr) Console.WriteLine(item); } } BURKE DAVID FRANK using System; usingSystem.Query; usingSystem.Collections.Generic; classapp { static void Main() { string[] names = { "Allen", "Arthur", "Bennett" }; IEnumerable<string> ayes = names .Where(s => s[0] == 'A'); foreach (string item in ayes) Console.WriteLine(item); names[0] = "Bob"; foreach (string item in ayes) Console.WriteLine(item); } } Allen Arthur using System; usingSystem.Query; usingSystem.Collections.Generic; classapp { static void Main() { string[] names = { "Burke", "Connor", "Frank", "Everett", "Albert", "George", "Harris", "David" }; Func<string, bool> filter = s => s.Length == 5; Func<string, string> extract = s => s; Func<string, string> project = s = s.ToUpper(); IEnumerable<string> expr = names .Where(filter) .OrderBy(extract) .Select(project); foreach (string item inexpr) Console.WriteLine(item); } } BURKE DAVID FRANK
LINQ to SQL <book> <title/> <author/> <year/> <price/> </book> Relational Objects XML .NET Language Integrated Query C# 3.0 Visual Basic 9.0 Others LINQ toObjects LINQ toDataSets LINQ toSQL LINQ toEntities LINQ toXML
LINQ to SQL Overview • ORM Редактор • Связывает реляционные структуры с классами • Отложенная подгрузка объемных данных • Можно выключить полностью • Можно включить избирательно (DataShape примененное кDataContext) • Таблицы используют CRUD Операции (Default = use runtime) • Могут указывать на хранимые процедуры
LINQ to SQL Architecture db.Customers.Add(c1); c2.City = “Seattle"; db.Customers.Remove(c3); from c in db.Customers where c.City == "London" select c.CompanyName Enumerate Objects SubmitChanges() SQL Queryor SProc Rows DML orSProcs SQL Server INSERT INTO Customer … UPDATE Customer …DELETE FROM Customer … SELECT CompanyName FROM Customer WHERE City = 'London' Application LINQ to SQL
The DataContext Class • На первый взгляд, кажется похожимна Connection object из ADO.NET • Queries • Commands • Transactions • Но имеет более расширенную функциональность: • Accessing objects in the object-relational framework • Base for derived database specialization (automated by gen tools) • Adds Caching and Tracking • And More
LINQ to XML <book> <title/> <author/> <year/> <price/> </book> Relational Objects XML .NET Language Integrated Query C# 3.0 Visual Basic 9.0 Others LINQ toObjects LINQ toDataSets LINQ toSQL LINQ toEntities LINQ toXML
LINQ to XML • Значительные усовершенствования существующей модели • Поддерживает: • Creating XML • Loading & querying XML • Modifying & saving XML • Streaming, Schema, Annotations, Events
LINQ to XML • Новый XML API реализованный в v3.5 assembly • System.Xml.Linq.dll • Namespaces • System.Xml.Linq • System.Xml.Schema • System.Xml.XPath • Можно использовать отдельно от LINQ
Ключевые классы в System.Xml.Linq • System.Xml.Linq это “DOM like” API • Манипулирование XML деревом в памяти • Возможность работы с документами и фрагментами • Два основных класса System.Xml.Linq
Загрузка Xml Content’а • Методы загрузки • XElement.Load • XDocument.Load • Можно применять к • URI, XmlReader, TextReader
Редактирование XML • XML деревосоставляется из вложенных экз.XElement. • Модификация осущ. методами: • XElement.Add() • XElement.Remove() • XElement.ReplaceWith() • Модифицируемое дерево м. б. сериализовано • XElement.Save(), XDocument.Save() • Both supporting filename, TextWriter, XmlWriter.
Создание XML документа XNamespace ns = "http://example.books.com"; XDocument books = new XDocument( new XElement(ns + "bookstore", new XElement(ns + "book", new XAttribute("ISBN", isbn), new XElement(ns + "title", "ASP.NET Book"), new XElement(ns + "author", new XElement(ns + "first-name", a.FirstName), new XElement(ns + "last-name", a.LastName) ) ) ) ); books.Save(@"C:\Books.xml");
VB 9: XML Литералы Dim books = <bookstore xmlns="http://examples.books.com"> <book ISBN=<%= isbn %>> <title>ASP.NET Book</title> <author> <first-name><%= a.FirstName %></first-name> <last-name><%= a.LastName %></last-name> </author> </book> </bookstore> books.Save("C:\Books.xml"); • XML можно использовать в коде • Компилируется в соот.XElementВыражение • Может быть Code-Driven и Dynamic • Включает LINQ Выражения
Вместо литерации в C# • Нет XML Литералов • “Paste XML as XElement” плагин • Add XML to Clipboard • Edit -> Past XML as XElement • Входит в примеры VS2008 • Help -> Samples