Скачать презентацию LINQ Language Integrated Query ü LINQ это Скачать презентацию LINQ Language Integrated Query ü LINQ это

10_C#_Методы_расширения_LINQ.pptx

  • Количество слайдов: 40

LINQ (Language Integrated Query) ü LINQ — это название набора технологий для интеграции непосредственно LINQ (Language Integrated Query) ü LINQ — это название набора технологий для интеграции непосредственно в язык C# (и в другие языки платформы. NET) запросов к поставщикам данных. ü LINQ поддерживается версиями. NET Framework 3. 0 и выше. ü LINQ — это на самом деле две сущности: • набор операторов, предоставляемых как методы для операций с наборами данных; • конструкции языка C# для поддержки запросов непосредственно в языке. ü Для поддержки LINQ в версию 3. 0 C# были введены новые конструкции языка C# : • расширяющие методы (extension methods); • лямбда-выражения; • тип var.

LINQ (Language Integrated Query) ü LINQ предоставляет модель для работы с данными из различных LINQ (Language Integrated Query) ü LINQ предоставляет модель для работы с данными из различных источников данных, в которой запрос является одним из структурных элементов языка. ü Многие операторы, включенные в LINQ, являются аналогами известных операций, например, Select. Many, Where, Join, Group. By ( всего около 50). ü В. NET Framework Standard Query Operators API определен шаблон для методов, поддерживающих операции, который не описывает, для каких наборов данных предназначены эти операции и как именно их следует реализовать. ü Шаблон реализуется «провайдерами LINQ» для различных источников данных и целевых сред (наборов в памяти, баз данных SQL, объектнореляционных систем (ORM), вычислительных кластеров HPC Server, временных и потоковых источников данных и т. д. ). ü Один из наиболее часто применяемых провайдеров — LINQ to Objects, он предоставляет полный набор LINQ-операторов, реализованных поверх IEnumerable. Это обеспечивает реализацию запросов в C#.

Методы расширения ü Методы расширения предоставляют возможность Методы расширения ü Методы расширения предоставляют возможность "добавить" новые методы в ранее определенные типы без перекомпиляции или определения нового производного типа. ü Методы расширения определяются как методы статического класса. Их первый параметр имеет модификатор this и определяет тип, для которого метод может работать как расширение. ü Метод расширения вызывается как экземплярный метод без первого параметра. ü Методы расширения имеют более низкий приоритет, чем экземплярные методы типа с тем же именем и сигнатурой. Компилятор сначала выполняет поиск совпадения с методами экземпляра типа и только, когда такого метода нет, выполняет поиск методов расширения и делает привязку к первому найденному методу расширения. ü Методы расширения не могут получить доступ к закрытым полям типа, для расширения которого они используются.

Определение и вызов метода расширения ü Чтобы определить свой метод расширения, надо • определить Определение и вызов метода расширения ü Чтобы определить свой метод расширения, надо • определить статический класс, который будет содержать метод расширения; • метод расширения в статическом классе должен иметь по меньшей мере такую же видимость, что и содержащий его статический класс; • первый параметр метода расширения должен иметь модификатор this, этот параметр определяет тип, для которого метод можно использовать как расширение. ü При вызове метода расширения • метод расширения вызывается как экземплярный; • первый параметр не указывается, так как представляет собой тип, к которому применяется оператор, - компилятору уже известен тип объекта.

Определение и вызов методов расширения. Пример interface IDemo { void F(string str); } class Определение и вызов методов расширения. Пример interface IDemo { void F(string str); } class Old_Class : IDemo { public void F 1 (string str) { Console. Write. Line(" F 1 from Old_Class " + str); } } public void F (string str) { Console. Write. Line(" F from Old_Class " + str); } class Program { static void Main(string[] args) { Old_Class obj = new Old_Class(); obj. F 1("111"); obj. F 2("222"); obj. F 3("333"); obj. Foo("abc"); } } string s = ""; s. Foo("efg"); static class Extentions_Class { public static void F 1 (this Old_Class obj, string str) { Console. Write. Line(" F 1 from Extentions_Class " + str); } public static void F 2 (this Old_Class obj, string str) { Console. Write. Line(" F 2 from Extentions_Class " + str); } // Метод расширения для типов, реализующих IDemo public static void F 3 (this IDemo obj, string str) { Console. Write. Line(" F 3 from Extentions_Class " + str); obj. F("Call F from F 3"); } public static void Foo (this object obj, string str) { Console. Write. Line(" Foo " + str); } } Вывод : F 1 from Old_Class 111 F 2 from Extentions_Class 222 F 3 from Extentions_Class 333 F from Old_Class Call F from F 3 Foo abc Foo efg

Неявно типизированные локальные переменные. Анонимные типы ü Начиная с версии 3. 0, в C# Неявно типизированные локальные переменные. Анонимные типы ü Начиная с версии 3. 0, в C# поддерживается ключевое слово var для объявления неявно типизированных локальных переменных. Эти переменные имеют строгую типизацию, как и при явном задании типа, их тип определяет компилятор. ü В примере переменная test_1 имеет тип string, переменная test_2 - тип double. var test_1 = “abc”; var test_2 = 1. 234; test_2 = 10; // test_1 = test_2; // ошибка при компиляции ü Ключевое слово var также используется при создании анонимных типов. ü Анонимные типы — это ссылочные типы (class), состоящие из одного или более открытых свойств, доступных только для чтения. Непосредственный базовый класс для анонимного типа – System. Object. ü Имя типа создается компилятором. Тип свойств определяется инициализаторами свойств. ü В примере создается анонимный тип с двумя свойствами: Title и Year. var v = new { Title = "Fortran", Year = 1962 }; Console. Write. Line("Title = " + v. Title);

Анонимные типы. Пример var v_1 = new { Title = Анонимные типы. Пример var v_1 = new { Title = "Fortran", Year = 1962 }; Console. Write. Line (v_1); Console. Write. Line (v_1. Title); var v_2 = new { Title = "Fortran", Year = 1962 }; Console. Write. Line (object. Reference. Equals(v_1, v_2)); v_1 = v_2; var v_3 = new { Name = "Fortran", Year = 1962 }; // v_3 = v_1; var v_4 = new { Title = "Fortran", Author = "Иванов", Date = Date. Time. Today }; Console. Write. Line (v_1. Get. Type()); Console. Write. Line (v_2. Get. Type()); Console. Write. Line (v_3. Get. Type()); Console. Write. Line (v_4. Get. Type()); object obj = v_1; Console. Write. Line (obj); ü В примере определяются три анонимных типа. ü С точки зрения среды CLR анонимный тип ничем не отличается от любого другого ссылочного типа, за исключением того, что он может быть приведен только к типу object. ü Обычно анонимный тип используется в запросе select для возврата подмножества свойств объектов из исходной коллекции. Вывод: { Title = Fortran, Year = 1962 } Fortran False <>f__Anonymous. Type 0`2[System. String, System. Int 32] <>f__Anonymous. Type 1`2[System. String, System. Int 32] <>f__Anonymous. Type 2`3[System. String, System. Date. Time] { Title = Fortran, Year = 1962 }

Статический класс Enumerable ü Запрос представляет собой выражение для получения данных из источника данных. Статический класс Enumerable ü Запрос представляет собой выражение для получения данных из источника данных. ü Стандартные операторы запросов к источникам данных реализованы как методы расширений статических классов Enumerable и Queryable. Классы находятся в сборке System. Core. dll в пространстве имен System. Linq. ü Стандартные операторы запросов применимы к объектам, реализующим интерфейсы IEnumerable или IQueryable. public interface IEnumerable { IEnumerator Get. Enumerator(); } public interface IEnumerator { object Current {get; } bool Move. Next(); void Reset(); } public interface IEnumerable : IEnumerable { IEnumerator Get. Enumerator (); } public interface IEnumerator : IDisposable, IEnumerator { T Current { get; } }

Выражения запросов. Пример ü Классы Book и Books. Library для примеров, в которых создаются Выражения запросов. Пример ü Классы Book и Books. Library для примеров, в которых создаются и выполняются запросы разных типов. partial class Books. Library : IEnumerable { List books = new List(); public List Books { get { return books; } } public bool Contains ( Book book) { return books. Contains(book); } partial class Book : IComparable, IComparable { public string Title { get; set; } public string Author { get; set; } public int Year { get; set; } public Book(string Title, string Author, int Year) { this. Title = Title; this. Author = Author; this. Year = Year; } public int Compare. To(Book other) { return this. Title. Compare. To(other. Title); } } } public int Compare. To(object obj) { return Year. Compare. To((obj as Book). Year); public override string To. String() { return Title + " " + Author + " " + Year; } public void Add. Book(Book book) { if (!books. Contains(book)) books. Add(book); } public bool Remove. Book(Book book) { if (!books. Contains(book)) return false; else { books. Remove(book); return true; } } public override string To. String() { string tmp = ""; foreach (Book book in books) tmp += "n " + book. To. String(); return tmp; } public IEnumerator Get. Enumerator() { return books. Get. Enumerator(); } IEnumerator IEnumerable. Get. Enumerator() { return books. Get. Enumerator(); } }

Выражения запросов. Пример ü В следующем примере создается и выполняется два раза выражение запроса. Выражения запросов. Пример ü В следующем примере создается и выполняется два раза выражение запроса. static void Main(string[] args) { Books. Library lib = new Books. Library(); Book book_1 = new Book("C# ", "Trey Nash", 2010); lib. Add. Book(book_1); Book book_2 = new Book("C++", "Bjarn Straustroup", 2008); lib. Add. Book(book_2); lib. Add. Book(new Book("C#", "Эндрю Троелсен", 2005)); lib. Add. Book(new Book("Темные аллеи", "Иван Бунин", 2004)); lib. Add. Book(new Book("Война и мир", "Лев Толстой", 2007)); Console. Write. Line("nn======= Query "); // Определение выражения запроса IEnumerable date. Query = from item in lib where item. Year > 2006 select item; Console. Write. Line("nn======= Первое выполнение запроса"); foreach (object book in date. Query) Console. Write. Line(book); Console. Write. Line("nn======= Второе выполнение запроса"); lib. Remove. Book(book_1); foreach (object book in date. Query) Console. Write. Line(book); Вывод : ======= Query ======= Первое выполнение запроса C# Trey Nash 2010 C++ Bjarn Straustroup 2008 Война и мир Лев Толстой 2007 ======= Второе выполнение запроса C++ Bjarn Straustroup 2008 Война и мир Лев Толстой 2007

Источник данных, создание и выполнение запроса ü Запрос представляет собой выражение для получения данных Источник данных, создание и выполнение запроса ü Запрос представляет собой выражение для получения данных из источника данных. ü Операция запроса LINQ включает • получение источника данных; • создание запроса; • выполнение запроса. ü В LINQ выполнение запроса отделено от самого запроса — создание переменной запроса само по себе не связано с получением данных, в ней просто хранятся сведения, необходимые для последующего выполнения запроса. ü Источник данных LINQ — это любой объект, поддерживающий универсальный интерфейс IEnumerable или интерфейс, наследуемый от него. ü Если источника данных нет в памяти в виде запрашиваемого типа, его предоставляет поставщик LINQ. Например, LINQ to XML загружает XMLдокумент в запрашиваемый тип XElement. ü Выполнение запроса происходит при использовании переменной запроса в операторе foreach.

Выражение запроса ü Все переменные в выражении запроса имеют строгую типизацию, хотя обычно нет Выражение запроса ü Все переменные в выражении запроса имеют строгую типизацию, хотя обычно нет необходимости явно указывать тип – компилятор сам его вычисляет. ü При компиляции выражения запросов преобразуются в вызовы методов расширения, которые поддерживают стандартные операторы запросов. ü Любой запрос, который может быть выражен с помощью синтаксиса запросов, также может быть выражен с помощью синтаксиса методов, нет различий в производительности. ü Синтаксис запросов и методов можно использовать одновременно. ü Некоторые запросы, например, Count или Max, не имеют соответствующих предложений в выражениях запросов, их можно создать только с помощью вызова методов.

Немедленное или отложенное выполнение запроса ü Переменная запроса хранит только команды запроса и не Немедленное или отложенное выполнение запроса ü Переменная запроса хранит только команды запроса и не содержит результатов запроса. Запросы выполняются одним из двух способов: немедленным или отложенным. ü При немедленном выполнении операция выполняется в той точке кода, где объявлен запрос. Немедленно выполняются все стандартные операторы запросов, возвращающие один неперечислимый результат, например, поиск максимального элемента или среднего значения. ü При отложенном выполнении запроса операция выполняется только после перечисления переменной запроса, например в операторе foreach. Результат выполнения запроса зависит от содержимого источника данных в момент выполнения запроса, а не при его определении. Один и тот же запрос может возвращать разные результаты, если между его выполнениями изменяются данные в источнике.

Сохранение результатов запроса в памяти ü Чтобы принудительно вызвать немедленное выполнение любого запроса и Сохранение результатов запроса в памяти ü Чтобы принудительно вызвать немедленное выполнение любого запроса и сохранить его результат, можно вызвать один из методов public static TSource[] To. Array( this IEnumerable source ); public static List To. List( this IEnumerable source ); public static Dictionary To. Dictionary ( this IEnumerable source, Func key. Selector );

Сохранение результатов запроса в памяти. Пример ü В примере результат запроса сохраняется в коллекции Сохранение результатов запроса в памяти. Пример ü В примере результат запроса сохраняется в коллекции List. Console. Write. Line("nn======= Books. Library"); foreach (object item in lib) Console. Write. Line(item); IEnumerable date. Query = from item in lib where item. Year > 2006 select item; Console. Write. Line("nn======= List"); List books_after_2006 = date. Query. To. List(); foreach (Book book in books_after_2006) Console. Write. Line(book); Console. Write. Line("nn======= Выполнение запроса"); foreach (object book in date. Query) Console. Write. Line(book); lib. Remove. Book(book_1); book_2. Year = 1999; Console. Write. Line("nn======= Следующее выполнение запроса"); foreach (object book in date. Query) Console. Write. Line(book); Console. Write. Line("nn======= List"); foreach (Book book in books_after_2006) Console. Write. Line(book); ======= Books. Library C# Trey Nash 2010 C++ Bjarn Straustroup 2008 C# Эндрю Троелсен 2005 Темные аллеи Иван Бунин 2004 Война и мир Лев Толстой 2007 ======= List C# Trey Nash 2010 C++ Bjarn Straustroup 2008 Война и мир Лев Толстой 2007 ======= Выполнение запроса C# Trey Nash 2010 C++ Bjarn Straustroup 2008 Война и мир Лев Толстой 2007 ======= Следующее выполнение запроса Война и мир Лев Толстой 2007 ======= List C# Trey Nash 2010 C++ Bjarn Straustroup 1999 Война и мир Лев Толстой 2007

Операции с данными, выполняемые с помощью стандартных операций запросов • Сортировка данных • Группировка Операции с данными, выполняемые с помощью стандартных операций запросов • Сортировка данных • Группировка данных • Операции над множествами • Операции создания • Фильтрация данных • Операции равенства • Операции квантификаторов • Операции с элементами • Операции проецирования • Преобразование типов данных • Разделение данных • Операции объединения • Операции соединения • Операции статистической обработки

Некоторые операции статистической обработки ü Статистические операции вычисляют одно неперечислимое значение для последовательности. ü Некоторые операции статистической обработки ü Статистические операции вычисляют одно неперечислимое значение для последовательности. ü Для этих операций нет соответствующих предложений в выражениях запросов, используются вызовы методов. Запрос выполняется в точке создания. Average Вычисляет среднее значение для элементов коллекции. 20 перегрузок. Перегружен для применения функции преобразования к каждому элементу входной последовательности. Count Возвращает число элементов в коллекции. Перегружен для подсчета элементов, которые удовлетворяют функции предиката. Max Возвращает максимальный элемент в коллекции. Более 20 перегрузок. Min Возвращает минимальный элемент в коллекции. Более 20 перегрузок. Sum Вычисляет сумму значений элементов последовательности. Перегружен для применения функции преобразования к каждому элементу входной последовательности.

Максимальный элемент. Примеры ü Метод возвращает максимальное значение в последовательности, реализующей IEnumerable<double> public static Максимальный элемент. Примеры ü Метод возвращает максимальное значение в последовательности, реализующей IEnumerable public static double Max( this IEnumerable source ); ü Следующая перегрузка возвращает максимальный элемент в последовательности, состоящей из элементов типа TSource, в котором реализован универсальный интерфейс IComparable или обычный IComparable. Приоритет имеет IComparable. public static TSource Max( this IEnumerable source ); ü Для коллекции из класса Books. Library максимальный элемент определяется реализацией универсального интерфейса IComparable. var book_max = lib. Max(); Console. Write. Line(book_max); ü Результат выполнения запроса Темные аллеи Иван Бунин 2004

Максимальный элемент. Пример 1 ü В классе Book реализованы интерфейсы IComparable<Book> и IComparable. ü Максимальный элемент. Пример 1 ü В классе Book реализованы интерфейсы IComparable и IComparable. ü В запросе Max() приоритет имеет IComparable. partial class Book : IComparable, IComparable { public string Title { get; set; } public string Author { get; set; } public int Year { get; set; } public Book(string Title, string Author, int Year) { this. Title = Title; this. Author = Author; this. Year = Year; } public int Compare. To(Book other) { return this. Title. Compare. To(other. Title); } public int Compare. To(object obj) { return Year. Compare. To((obj as Book). Year); } } public override string To. String() { return Title + " " + Author + " " + Year; } var book_max = lib. Max(); Console. Write. Line(book_max); ü Исходная последовательность: C# Trey Nash 2010 C++ Bjarn Straustroup 2008 C# Эндрю Троелсен 2005 Темные аллеи Иван Бунин 2004 Война и мир Лев Толстой 2007 ü Результат выполнения запроса: Темные аллеи Иван Бунин 2004

Максимальный элемент. Пример 2 ü Первый метод расширения вызывает функцию преобразования ( отвечающую делегату Максимальный элемент. Пример 2 ü Первый метод расширения вызывает функцию преобразования ( отвечающую делегату Func ) для каждого элемента последовательности и возвращает максимальное значение типа int. ü Второй метод вызывает функцию преобразования, отвечающую делегату Func. Для сравнения значений типа TResult используется интерфейс IComparable или IComparable. public static int Max ( this IEnumerable source, Func selector ); public static TResult Max( this IEnumerable source, Func selector ): ü В примере для запросов к последовательности элементов из класса Books. Library используются лямбда-выражения для функций преобразований. Console. Write. Line("nn======= Books. Library"); foreach (object item in lib) Console. Write. Line(item); var max_book_1 = lib. Max(x => x. Title. Length); Console. Write. Line(max_book_1); var max_book_2 = lib. Max(x => x. Author[0]); Console. Write. Line(max_book_2); ======= Books. Library C# Trey Nash 2010 C++ Bjarn Straustroup 2008 C# Эндрю Троелсен 2005 Темные аллеи Иван Бунин 2004 Война и мир Лев Толстой 2007 12 Э

Выражения запросов ü Для создания выражений запросов LINQ в C# добавлены новые ключевые слова Выражения запросов ü Для создания выражений запросов LINQ в C# добавлены новые ключевые слова from let by join ascending in where descending orderby group on select into equals ü Выражение запроса начинается с предложения from и оканчивается предложением select или group. ü Между ними может содержаться одно или несколько необязательных предложений where, orderby, join, let или других предложений from. IEnumerable date. Query = from book in lib where book. Year > 2006 select book; ü При компиляции выражения запросов преобразуются в вызовы методов расширения, которые поддерживают стандартные операторы запросов.

Предложение from ü Предложение from задает источник данных вместе с переменной диапазона - локальной Предложение from ü Предложение from задает источник данных вместе с переменной диапазона - локальной переменной для представления элемента входной последовательности. ü Переменная диапазона строго типизирована, ее тип определяется на основе типа элементов в источнике данных. ü В следующем примере переменная диапазона item имеет тип Book, так как определенный в классе Books. Library итератор последовательно возвращает элементы из коллекции List. Books. Library lib = new Books. Library(); IEnumerable date. Query = from item in lib where item. Year > 2006 select item;

Предложение select ü Выражение запроса должно завершаться предложением select или group. ü Простое предложение Предложение select ü Выражение запроса должно завершаться предложением select или group. ü Простое предложение select создает последовательность объектов с тем же типом, как и у элементов исходной последовательности. ü С помощью предложения select можно создавать последовательности объектов новых типов. Такое преобразование называют проекцией. ü При компиляции предложение select преобразуется в вызов одного из методов расширения public static IEnumerable Select( this IEnumerable source, Func selector ); public static IEnumerable Select( this IEnumerable source, Func selector ); ü Второй параметр методов расширения Select задает функцию преобразования, которая применяется к каждому элементу. ü Во второй перегрузке метода функция преобразования, которая применяется к каждому элементу, может использовать индекс элемента.

Операции проецирования. Пример ü В следующем примере • в первом запросе предложение select создает Операции проецирования. Пример ü В следующем примере • в первом запросе предложение select создает проекцию, состоящую из объектов типа string со значениями свойства Title переменной диапазона; • во втором запросе предложение select создает проекцию, состоящую из объектов анонимного типа, который имеет свойства типа string и типа int. var Query_1 = from item in lib select item. Title; foreach (var item in Query_1) Console. Write. Line(item); var Query_2 = from item in lib select new { Name = item. Title, Year = item. Year }; foreach (var item in Query_2) Console. Write. Line(item); ü Исходная последовательность ======= Books. Library C# Trey Nash 2010 C++ Bjarn Straustroup 2008 ü Результат выполнения запросов C# C++ { Name = C#, Year = 2010 } { Name = C++, Year = 2008 }

Фильтрация данных. Предложение where ü Фильтрацией называется операция выбора элементов, которые удовлетворяют заданному условию. Фильтрация данных. Предложение where ü Фильтрацией называется операция выбора элементов, которые удовлетворяют заданному условию. ü В языке запросов для фильтрации используется предложение where, которое при компиляции преобразуется в вызов одного из следующих методов расширения public static IEnumerable Where( this IEnumerable source, Func predicate ); public static IEnumerable Where( this IEnumerable source, Func predicate ); ü Методы возвращают последовательность элементов, удовлетворяющих условию предиката. Во второй перегрузке метода индекс каждого элемента можно использовать в логике функции предиката.

Фильтрация данных. Пример 1 ü В примере из коллекции класса Books. Library выбираются только Фильтрация данных. Пример 1 ü В примере из коллекции класса Books. Library выбираются только те элементы, в название которых входит подстрока C#. var Query_1 = from item in lib where item. Title. Contains("C#") select item; foreach (Book book in Query_1) Console. Write. Line(book); ü Тот же самый запрос можно реализовать в форме вызова метода расширения с использованием для предиката лямбда-выражения или обычного метода var Query_2 = lib. Where(x => x. Title. Contains("C#")); foreach (Book book in Query_2) Console. Write. Line(book); var Query_3 = lib. Where( selector_by_title ); foreach (Book book in Query_3) Console. Write. Line(book); ü Метод selector_by_title отвечает делегату Func. static bool selector_by_title( Book book) { return book. Title. Contains("C#"); }

Фильтрация данных. Пример 2 ü В одном предложении where можно указать несколько предикатов, если Фильтрация данных. Пример 2 ü В одном предложении where можно указать несколько предикатов, если использовать операторы && и ||. ü В следующем примере из коллекции класса Books. Library выбираются только те элементы, в название которых входит подстрока C# или подстрока C++. var Query_4 = from item in lib where item. Title. Contains("C++") || item. Title. Contains("C#") select item; foreach (Book book in Query_4) Console. Write. Line(book); ü Исходная последовательность ======= Books. Library C# Trey Nash 2010 C++ Bjarn Straustroup 2008 C# Эндрю Троелсен 2005 Темные аллеи Иван Бунин 2004. . ü Результат выполнения запроса C# Trey Nash 2010 C++ Bjarn Straustroup 2008 C# Эндрю Троелсен 2005

Фильтрация данных. Пример 3 ü Предложение where может содержать методы, возвращающие значения булевского типа. Фильтрация данных. Пример 3 ü Предложение where может содержать методы, возвращающие значения булевского типа. В следующем примере предложение where использует метод, проверяющий выполнение некоторого условия. var Query_5 = from item in lib where complex_selector (item) select item. Author; foreach (string author in Query_5) Console. Write. Line(author); ü Метод, проверяющий выполнение условия: static bool complex_selector(Book book) { return book. Author[0]=='B'; } ü Исходная последовательность ======= Books. Library C# Trey Nash 2010 C++ Bjarn Straustroup 2008 C# Эндрю Троелсен 2005 Темные аллеи Иван Бунин 2004 ü Результат выполнения запроса Bjarn Straustroup

Сортировка ü Предложение orderby используется для сортировки результатов в порядке возрастания или убывания. ü Сортировка ü Предложение orderby используется для сортировки результатов в порядке возрастания или убывания. ü Сортировка использует функцию сравнения для элементов типа T на основе: • универсального интерфейса System. IComparable, если он реализован в типе T; • обычного интерфейса System. IComparable, если тип T не реализует System. IComparable. ü При компиляции предложение orderby преобразуется в вызов одного из методов расширения public static IOrdered. Enumerable Order. By( this IEnumerable source, Func key. Selector ); public static IOrdered. Enumerable Order. By( this IEnumerable source, Func key. Selector, IComparer comparer ) ; ü Методы сортируют элементы последовательности в порядке возрастания ключа. Функция, которая каждому элементу TSource ставит в соответствие ключ TKey, передается как параметр. ü Методы выполняют строгую сортировку - если ключи двух элементов равны, порядок этих элементов сохраняется.

Сортировка. Пример ü При выполнении сортировки можно задать порядок дополнительной сортировки. ü В следующем Сортировка. Пример ü При выполнении сортировки можно задать порядок дополнительной сортировки. ü В следующем примере выполняется основная сортировка объектов Book по свойству Title в порядке убывания, дополнительная сортировка выполняется по свойству Year. По умолчанию выполняется сортировка по возрастанию. var Query_6 = from item in lib orderby item. Title descending, item. Year select item; foreach (Book book in Query_6) Console. Write. Line(book); ü До сортировки C# Trey Nash 2010 C++ Bjarn Straustroup 2008 C# Эндрю Троелсен 2005 Темные аллеи Иван Бунин 2004 Война и мир Лев Толстой 2007 ü После сортировки Темные аллеи Иван Бунин 2004 Война и мир Лев Толстой 2007 C++ Bjarn Straustroup 2008 C# Эндрю Троелсен 2005 C# Trey Nash 2010 ü Дополнительная сортировка выполняется методами расширения Then. By и Then. By. Descending.

Группирование данных ü Группированием называется операция размещения по группам данных с равными значениями ключа. Группирование данных ü Группированием называется операция размещения по группам данных с равными значениями ключа. ü Для группировки используется предложение group в форме group … by или group … by … into …. , которые при компиляции преобразуются в вызов одного из методов расширения Group. By (8 перегрузок) public static IEnumerable> Group. By( this IEnumerable source, Func key. Selector ); ü Группировка элементов последовательности выполняется по значению ключа TKey, который для каждого элемента TSource исходной последовательности вычисляется с помощью функции key. Selector. ü Метод возвращает коллекцию объектов IGrouping для каждого найденного в последовательности значения ключа. ü Интерфейс IGrouping представляет собой коллекцию объектов, имеющих равные значения ключа. public interface IGrouping : IEnumerable, IEnumerable ü Кроме унаследованных членов интерфейс имеет свойство TKey { get; }

Группирование данных. Пример ü В следующем примере в первом запросе выполняется группировка объектов Book Группирование данных. Пример ü В следующем примере в первом запросе выполняется группировка объектов Book по первому символу в свойстве Title, во втором запросе – свойства Title по числу символов в значении свойства. var Query_8 = from item in lib group item by item. Title[0]; foreach (var group in Query_8) { Console. Write. Line("n Key = " + group. Key ); foreach (Book book in group) Console. Write. Line(book); } var Query_9 = from item in lib group item. Title by item. Title. Length; foreach (var group in Query_9) { Console. Write. Line(“ Key = " + group. Key); ü Результат выполнения запроса 1 foreach (object item in group) Console. Write. Line(item); } ü Исходная последовательность ü Результаты выполнения запросов ======= Books. Library C# Trey Nash 2010 C++ Bjarn Straustroup 2008 C# Эндрю Троелсен 2005 Темные аллеи Иван Бунин 2004 Война и мир Лев Толстой 2007 Key = C C# Trey Nash 2010 C++ Bjarn Straustroup 2008 C# Эндрю Троелсен 2005 Key = Т Темные аллеи Иван Бунин 2004 Key = В Война и мир Лев Толстой 2007 Key = 2 C# C# Key = 3 C++ Key = 12 Темные аллеи Key = 11 Война и мир

Группировка по составному ключу ü Группировка по нескольким ключам выполняется с помощью составных ключей. Группировка по составному ключу ü Группировка по нескольким ключам выполняется с помощью составных ключей. Для составного ключа можно использовать анонимный тип. ü В следующем примере выполняется группировка объектов Book по значениям свойств Author и Year. В запросе используется анонимный тип. var Query_10 = from item in lib group item by new { key 1 = item. Title, key 2 = item. Year }; foreach (var group in Query_10) { Console. Write. Line("n Key = " + group. Key); foreach (object item in group) Console. Write. Line(item); } ü Исходные данные : ======= Books. Library C# Trey Nash 2010 C++ Bjarn Straustroup 2008 C# Эндрю Троелсен 2005 C# Герберт Шилдт 2005 ü Результат : Key = { key 1 = C#, key 2 = 2010 } C# Trey Nash 2010 Key = { key 1 = C++, key 2 = 2008 } C++ Bjarn Straustroup 2008 Key = { key 1 = C#, key 2 = 2005 } C# Эндрю Троелсен 2005 C# Герберт Шилдт 2005

Предложение into ü Если после операций выбора или группирования , выполняются другие операции, в Предложение into ü Если после операций выбора или группирования , выполняются другие операции, в предложениях select и group можно использовать ключевое слово into для создания временного идентификатора, в котором хранится запрос. ü В примере сначала выполняется группировка по значению свойства Title, а затем отбираются только группы, содержащие более одного элемента. var Query_11 = from item in lib group item by item. Title into title. Group where title. Group. Count() > 1 select title. Group; foreach (var group in Query_11) { Console. Write. Line("n Key = " + group. Key); foreach (object item in group) Console. Write. Line(item); } ü Исходные данные : ======= Books. Library C# Trey Nash 2010 C++ Bjarn Straustroup 2008 C# Эндрю Троелсен 2005 C# Герберт Шилдт 2005 C++ Herbert Schildt 1998 Темные аллеи Иван Бунин 2004 Война и мир Лев Толстой 2007 ü Результат : Key = C# C# Trey Nash 2010 C# Эндрю Троелсен 2005 C# Герберт Шилдт 2005 Key = C++ Bjarn Straustroup 2008 C++ Herbert Schildt 1998

Предложение let ü Предложение let создает и инициализирует новую переменную диапазона, которую можно использовать Предложение let ü Предложение let создает и инициализирует новую переменную диапазона, которую можно использовать в следующих предложениях. ü В следующем примере создается новая переменная диапазона с именем names, сохраняющая результат вызова метода Split для свойства Author, которая затем используется в запросе сортировки по длине строк. var Query_12 = from item in lib let names = item. Author. Split(' ') from name in names orderby name. Length select name; foreach (var item in Query_12) Console. Write. Line(item); ü Исходные данные : ======= Books. Library C# Trey Nash 2010 C++ Bjarn Straustroup 2008 C# Эндрю Троелсен 2005 C++ Herbert Schildt 1998 ü Результат : Trey Nash Bjarn Эндрю Herbert Schildt Троелсен Straustroup

Операции соединения ü Соединение — это операция связывания элементов из двух источников данных на Операции соединения ü Соединение — это операция связывания элементов из двух источников данных на основе общего ключа. ü LINQ поддерживает два метода соединения Join и Group. Join, которые выполняют объединение по эквивалентности — соединение двух источников данных на основании совпадения их ключей. ü Операции выполняются над двумя последовательностями с элементами разных типов. Можно использовать анонимный тип, чтобы объединить свойства связанных элементов в новый тип для выходной последовательности. ü Запрос join … on … equals … cоединяет две последовательности на основе функции выбора ключа и извлекает пары значений. ü Запрос join … on … equals … into … соединяет две последовательности на основе функции выбора ключа и группирует полученные совпадения для каждого элемента.

 Операции соединения ü Запрос join … on … equals … компилируется в метод Операции соединения ü Запрос join … on … equals … компилируется в метод расширения public static IEnumerable Join( this IEnumerable outer, IEnumerable inner, Func outer. Key. Selector, Func inner. Key. Selector, Func result. Selector ) ; TOuter - тип элементов первой последовательности; TInner -тип элементов второй последовательности; TKey -тип ключей; TResult -тип результирующих элементов; result. Selector - функция для создания результирующего элемента.

Операции квантификаторов ü Квантификаторы возвращают значение булевского типа, которое указывает, удовлетворяют ли условию некоторые Операции квантификаторов ü Квантификаторы возвращают значение булевского типа, которое указывает, удовлетворяют ли условию некоторые или все элементы в последовательности. Выполняются только с помощью вызовов методов расширения. All Определяет, все ли элементы последовательности удовлетворяют условию. Any Определяет, удовлетворяют ли некоторые элементы последовательности условию. Contains Определяет, содержит ли последовательность указанный элемент. Некоторые операции с элементами ü Операции с элементами возвращают один определенный элемент из последовательности. Выполняются только с помощью вызовов методов расширения. First Возвращает первый элемент коллекции, удовлетворяющий условию, или генерирует исключение. First. Or. Default Возвращает первый элемент коллекции, удовлетворяющий условию, или значение по умолчанию. Single Возвращает единственный элемент коллекции элемент, удовлетворяющий условию, или генерирует исключение.

Операции над множествами ü Операции образуют последовательность, основанную на наличии или отсутствии совпадающих элементов Операции над множествами ü Операции образуют последовательность, основанную на наличии или отсутствии совпадающих элементов внутри одной или двух последовательностей. Выполняются только с помощью вызовов методов расширения. ü Разные перегрузки методов используют метод проверки на равенство элементов по умолчанию или метод, который передается как параметр. Distinct Удаляет повторяющиеся значения из последовательности. Except Возвращает разность множеств — набор элементов одной коллекции, которые не содержатся во второй коллекции. Intersect Возвращает пересечение множеств. Union Возвращает объединение множеств.

Операции разделения данных ü Операции выполняют разделение входной последовательности на два раздела без изменения Операции разделения данных ü Операции выполняют разделение входной последовательности на два раздела без изменения порядка элементов. Выполняются только с помощью вызовов методов расширения. Skip Пропускает заданное число элементов последовательности. Skip. While Пропускает элементы, которые удовлетворяют условию функции предиката, до тех пор, пока не встретится элемент, для которого условие не выполнено. Возвращает оставшиеся элементы. Take Принимает заданное число элементов с начала последовательности. Take. While Принимает элементы до тех пор, пока элемент не удовлетворит условию функции предиката.