Linq to sql, запити до бази даних

»» В ЦІЙ СТАТТІ ВИКОРИСТОВУЄТЬСЯ ВИХІДНИЙ КОД ДЛЯ ПРИКЛАДІВ

Виконання запитів LINQ to SQL схоже на виконання будь-якого іншого запиту LINQ, але з кількома винятками. Розглянемо їх дуже коротко.

Щоб виконати запит LINQ to SQL, спочатку потрібно буде зробити DataContext. Потім можна виконувати запит в таблицю всередині цього DataContext:

Коли виконується цей код, замовник, CustomerID якого дорівнює "EASTC", витягується в змінну cust. Однак слід мати на увазі, що, стандартна операція запиту Single згенерує виняток, якщо послідовність, на якій вона визванa, не містить відповідних елементів. Тому в даному випадку потрібно точно знати, що замовник "EASTC" існує. Насправді стандартна операція запиту SingleOrDefault забезпечує кращий захист на випадок, якщо не знайдеться записи, відповідної конструкції where.

У цьому прикладі необхідно відзначити ще пару моментів. По-перше, зверніть увагу, що в запиті при порівнянні CustomerID з "EASTC" використовується синтаксис C #. Про це говорить застосування подвійних лапок замість одинарних, як того вимагає синтаксис SQL.

До того ж використовується операція перевірки еквівалентності C # == замість операції перевірки еквівалентності SQL =. Це демонструє той факт, що запит насправді інтегрований в мову: в кінці кінців, це випливає з самої назви LINQ - мова інтегрованих запитів.

По-друге, зверніть увагу, що в цьому запиті синтаксис виразів запиту змішується зі стандартним синтаксисом точкової нотації. Частина, представлена ​​в синтаксисі виразів запитів, укладена в дужки, а операція Single викликається із застосуванням стандартної точкової нотації.

А тепер питання. Чи викличе запуск наведеного коду негайне виконання запиту? Обдумуючи відповідь, не забудьте про відкладений виконанні запитів. Відповідь: так, стандартна операція запиту Single викличе негайне виконання запиту. Якщо виключити виклик цієї операції і негайно повернути результат запиту, то клопотання не буде виконаний негайно.

Код вище не видає ніякого екранного виведення, тому просто щоб переконатися, що код дійсно отримає відповідного замовника, в наступному прикладі наведено той же код, але з додаванням виведення на екран, що відображає витягнуту запис про замовника:

Нижче показаний висновок:

Linq to sql, запити до бази даних

Раніше згадувалося, що запити LINQ to SQL подібні звичайним запитам LINQ, але з деякими винятками. Давайте обговоримо ці винятки:

Запити LINQ to SQL повертають IQueryable

У той час як запити LINQ, виконані на масивах і колекціях, повертають послідовності IEnumerable, запити LINQ to SQL, запитують цю послідовність, повертають послідовність типу IQueryable. Нижче наведено приклад запиту, повертає послідовність типу IQueryable:

Як бачите, типом повернення цього запиту є IQueryable. Ось результат виконання коду:

Linq to sql, запити до бази даних
">

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

Запити LINQ to SQL виконуються на об'єктах Таble<Т>

У той час як більшість звичайних запитів LINQ виконуються на масивах і колекціях, що реалізують інтерфейси IEnumerable або IEnumerable, запит LINQ to SQL виконується на класах, що реалізують інтерфейс IQueryable, такому як Table<Т>.

Це означає, що запитам LINQ to SQL доступні додаткові операції запитів, поряд зі стандартними операціями запитів, оскільки IQueryable реалізує IEnumerable.

Запити LINQ to SQL транслюються в SQL

Оскільки запити LINQ to SQL повертають послідовність типу IQueryable, вони не компілюються в код проміжного мови .NET, як це роблять звичайні запити LINQ. Замість цього вони перетворюються в дерева виразів, що дозволяє їм обчислюватися як єдине ціле і транслюватися в відповідні і оптимальні конструкції SQL. Прочитайте статтю Трансляція SQL. щоб дізнатися більше про трансляцію SQL, яка відбувається в запитах LINQ to SQL.

Запити LINQ to SQL виконуються в базі даних

На відміну від запитів LINQ, які виконуються в пам'яті локальної машини, запити LINQ to SQL транслюються в виклики SQL, які в дійсності виконуються в базі даних. Через це відбувається деяка розбіжність, таке як спосіб обробки проекції, яка не може в дійсності траплятися в базі даних, оскільки база нічого не знає про сутнісних класах, як і про будь-яких інших класах.

До того ж, оскільки запит насправді виконується в базі даних, і база не має доступу до коду вашої програми, то, що можна зробити в запиті, повинно транслюватися, що обмежує його деяким чином в залежності від можливостей транслятора. Не можна просто вбудувати виклик написаного методу в лямбда-вираз і очікувати, що SQL Server здогадається, що потрібно робити з викликом. Через це непогано б знати, що може транслюватися, у що він може бути трансльовано, і що трапиться, коли трансляція неможлива.