Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
5fan_ru_ПАРАДИГМИ ПРОГРАМУВАННЯ.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
3.32 Mб
Скачать

1.1 Джерело даних

У попередньому прикладі джерелом даних був масив, тому він неявно підтримує універсальний інтерфейс IEnumerable<(Of <(T>)>). Це означає, що до нього можна виконувати запити з LINQ. Запит виконується в операторі foreach, і оператору foreach потрібний інтерфейс IEnumerable або IEnumerable<(Of <(T>)>). Типи, які підтримують IEnumerable<(Of <(T>)>) або похідні інтерфейси, такі як універсальний інтерфейс IQueryable<(Of <(T>)>), називаються запрошуваними типами.

Інтерфейс це повністю абстрактний клас, всі методи якого абстрактні (не містять реалізації).

Якщо клас можна розглядати як деякий контейнер об'єктів перечислення, то для того, щоб клас міг повертати ці об'єкти в циклі for each, клас має бути спадкоємцем інтерфейсу IEnumerable або мати в своєму складі ітератори - методи, які повертають результат типа IEnumerable.

Для запрошуваного типа, як джерело даних LINQ, не потрібні зміни або спеціальна обробка. Якщо джерело даних ще не знаходиться в пам'яті у вигляді запрошуваного типа, постачальник LINQ повинен представити його як такий. Наприклад, LINQ to XML завантажує XML-документ в запрошуваний тип XElement:

// Створення джерела даних з XML-документа, використовуючи System.Xml.Linq

XElement contacts = XElement.Load(@"c:\myContactList.xml");

Використовуючи LINQ to SQL, спочатку вручну або за допомогою конструктора об'єктів створюється об'єктно-реляційне зіставлення в режимі розробки. Потім можна написати запити до об'єктів, а під час виконання LINQ to SQL здійснюватиме взаємодію з базою даних. У наступному прикладі Customer представляє певну таблицю в базі даних, а Table<Customer> підтримує універсальний інтерфейс IQueryable<(Of <(T>)>), похідний від IEnumerable<(Of <(T>)>):

// Створення джерела даних з бази даних SQL Server, використовуючи System.Data.Linq

DataContext db = new DataContext(@"c:\northwind\northwnd.mdf");

1.2. Запит

Запит вказує, яку інформацію потрібно витягувати з джерела або джерел даних. При необхідності, запит також вказує спосіб сортування, групування і формування цих відомостей перед поверненням. Запит зберігається в змінній запиту і ініціалізується виразом запиту. Аби спростити написання запитів, в C# з'явився новий синтаксис запиту.

Запит з попереднього прикладу повертає всі парні числа з масиву цілих чисел. Вираз запиту містить три ключові слова: from, where і select. Слово from вказує джерело даних, where застосовує фільтр, а select вказує тип результату. Важливо, що в LINQ сама змінна запиту не виконує дій і не повертає жодних даних. Вона просто зберігає відомості, необхідні для надання результатів при подальшому виконанні запиту.

1.3. Виконання запиту

Виконання запиту розділяють на відкладене і примусове (негайне).

Як вже говорилося раніше, сама змінна запиту лише зберігає команди запиту. Фактичне виконання запиту відкладається до виконання ітерації змінної запиту в операторі foreach. Цю концепцію називають відкладеним виконанням, вона показана в наступному прикладі:

// Виконання запиту

foreach (int num in numQuery)

{

Console.Write("{0,1} ", num);

}

Оператор foreach є також місцем, де витягуються результати запиту. Наприклад, в попередньому запиті змінна ітерації num містить кожне (по черзі) значення в послідовності, що повертається.

Запити, що виконують статистичні функції над діапазоном вихідних елементів, повинні спочатку виконати ітерацію цих елементів. Прикладами таких запитів є Count, Мах, Average і First. Вони виконуються без явного оператора foreach, оскільки сам запит повинен використовувати foreach для повернення результату. Зверніть увагу, що такий тип запитів повертає одне значення, а не колекцію IEnumerable. Наступний запит повертає кількість парних чисел у вихідному масиві:

var evenNumQuery =

from num in numbers

where (num % 2) == 0

select num;

int evenNumCount = evenNumQuery.Count();

Аби примусово викликати негайне виконання будь-якого запиту і кешувати його результати, можна викликати метод ToList<(Of <(TSource>)>) або ToArray<(Of <(TSource>)>):

List<int> numQuery2 =

(from num in numbers

where (num % 2) == 0

select num).ToList();

// або так:

// numQuery3 – це було int[]

var numQuery3 =

(from num in numbers

where (num % 2) == 0

select num.ToArray();

Можна також примусово виконати запит, помістивши цикл foreach відразу після вираження запиту. Проте виклик ToList або ToArray також кэширует всі дані в одній колекції об'єктів.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]