Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
opi.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.81 Mб
Скачать

Відкладені запити linq.

У табл. 1 міститься стовпчик "Відкладений". Запит, який містить тільки відкладені методи, не виконується доти, поки елементи в результаті IEnumerable < T > не будуть перераховані, як показано в лістингу 9.

Лістинг 9. Використання відкладених методів розширення LINQ в запиті

using System ;

using System.Linq;

class Program {

static void Main (string [] args) {

Product [] products = {

new Product {Name = "Kayak", Category = "Watersports", Price = 275M},

new Product {Name = "Lifejacket", Category = "Watersports", Price = 48.95M},

new Product {Name = "Soccer ball", Category = "Soccer", Price = 19.50M},

new Product {Name = "Corner flag", Category = "Soccer", Price = 34.95M}

};

var results = products

.OrderByDescending (e => e.Price)

.Take (3)

.Select (e => new { e.Name, e.Price });

products [2] = new Product {Name = "Stadium", Price = 79500M};

foreach (var р in results) {

Console.WriteLine ("Item: {0}, Cost: {1} ", p.Name, p.Price);

}

}

}

У цьому прикладі ми створюємо масив об'єктів Product , а потім визначаємо запит, який був використаний у попередньому розділі. Після того як запит визначений, ми змінюємо один з об'єктів в масиві Product , а потім виконуємо перерахування результатів запиту. Виведення цього прикладу має наступний вигляд:

Item : Stadium , Cost : 79500

Item : Kayak , Cost : 275

Item : Lifejacket , Cost : 48.95

Тобто запит не обробляється до тих пір, поки результати не будуть перераховані, і тому внесена зміна – додавання елемента Stadium в масив Product – відображається у виведенні. І навпаки, використання будь-якого з НЕ відкладених методів розширення веде до негайного виконання запиту LINQ . Така ситуація продемонстрована в лістингу 10.

Лістинг 10. Негайне виконання запиту LINQ

using System ;

using System.Linq;

class Program {

static void Main (string [] args) {

Product [] products = {

new Product {Name = "Kayak", Category = "Watersports", Price = 275M},

new Product {Name = "Lifejacket", Category = "Watersports", Price = 48.95M},

new Product {Name = "Soccer ball", Category = "Soccer", Price = 19.50M},

new Product {Name = "Corner flag", Category = "Soccer", Price = 34.95M}

};

var results = products.Sum (e => e.Price)

products [2] = new Product {Name = "Stadium", Price = 79500M};

Console.WriteLine ("Sum: (0: c}", results);

}

}

У цьому прикладі використовується метод Sum і генерується наступний результат:

Sum : $ 378.40

Як бачите, елемент Stadium , зі свого значно більш високою ціною, не був включений в результати.

Повторне використання відкладеного запиту

Цікава особливість, яка породжується відкладеними методами розширення LINQ , пов'язана з тим, що запити обробляються заново при кожному перерахуванні результатів, як показано в лістингу 11.

Лістинг 11. Повторне виконання відкладеного запиту

using System ;

using System.Linq;

class Program {

static void Main (string [] args) {

Product [] products = {

new Product {Name = "Kayak", Category = "Watersports", Price = 275M},

new Product {Name = "Lifejacket", Category = "Watersports", Price = 48.95M},

new Product {Name = "Soccer ball", Category = "Soccer", Price = 19.50M},

new Product {Name = "Corner flag", Category = "Soccer", Price = 34.95M}

};

var results = products

.OrderByDescending (e => e.Price)

.Take (3)

.Select (e => new { e.Name, e.Price });

foreach (var p in results) {

Console.WriteLine ("Item: {0}, Cost: {1}", p.Name, p.Price);

}

Console.WriteLine(“--- End of results --- ");

products [2] = new Product {Name = "Stadium", Price = 79500M};

foreach (var р in results) {

Console.WriteLine ("Item: {0}, Cost: {1} ", p.Name, p.Price);

}

}

}

Цей приклад створює дані, визначає відкладений запит LINQ , а потім перераховує результати запиту. Один з елементів даних змінюється, і результати перераховуються ще раз. Результати цього прикладу мають наступний вигляд:

Item : Kayak , Cost : 275

Item : Lifejacket , Cost : 48.95

Item: Corner flag, Cost: 34.95

--- End of results ---

Item: Stadium, Cost: 79500

Item: Kayak, Cost: 275

Item: Lifejacket, Cost: 48.95

--- End of results ---

Як бачимо, зміна даних відображається при другому перерахування результатів. Нам не довелося перевизначати, оновлювати або якось інакше модифіковані запит L 1 NQ . Це означає, що можна завжди покладатися на відкладений запит при відображенні самих останніх змін у джерелі даних, але це означає також, що результати запиту не кешируются. Якщо потрібно кешувати результати запиту, слід використовувати не відкладений метод, такий як ТоАггау, який приведе до негайного виконання запиту.

LINQ і інтерфейс IQueryable < T >

Існують різні варіації LINQ, хоча його використання багато в чому залишається незмінним Одним з різновидів є LINQ To Objects , який ми використовували до сих пір в прикладах до цієї теми. LINQ To Objects дозволяє запитувати об'єкти С#, які постійно зберігаються у пам'яті. Інший різновид – LINQ To XML – є дуже зручним і надає великі можливості способом створення, обробки і запиту XML-вмісту. Паралельно з LINQ існує піднабір LINQ To Objects, який підтримує одночасне виконання запитів кількома процесорами або ядрами системи.

Для нас особливий, інтерес представляє варіація LINQ To Entities, яка дозволяє виконувати запити LINQ у відношені до даних, отриманих від Entity Framework. Слід зазначити, що Entity Framework – це ORM-платформа Microsoft, яка є частиною більш широкої платформи ADO.NET. ORM дозволяє працювати з реляційними даними, використовуючи об'єкти C#, і саме цей механізм буде застосовуватися нами далы книзі для отримання доступу до даних, що зберігаються в базах даних .

Використання Entity Framework і LINQ To Entities буде показано в наступній чолі , але , представляючи LINQ , ми хотіли б згадати про інтерфейсі IQueryable < T >.

Інтерфейс IQueryable <T> є похідним від інтерфейсу IEnumerable <T> і використовується для вираження результату запиту , виконаного у відношенню до конкретного джерела даних . У наших прикладах таким джерелом буде база даних SQL Server . Ні ніякої необхідності працювати з IQueryable < T > безпосередньо . Одна з чудових особливостей LINQ складається в тому , що один і той ж запит може виконуватися у відношенні до безлічі типів джерел даних (об'єктів, XML, баз даних і т . д .). Використання IQueryable < T > підкреслюватиме, що робота виконується з даними , які надходять з бази .

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