Часто задаваемые вопросы о LINQ - часть первая
ОГЛАВЛЕНИЕ
Введение и цель
В данном разделе разобраны основы LINQ и показаны 5 основных запросов LINQ, которые всегда нужны в проекте для запросов. Во время изучения основ будет объяснено, какую проблему LINQ решает с позиции бизнес-объектов среднего уровня.
Другие часто задаваемые вопросы о LINQ
Во второй части FAQ-а показаны базовый пример LINQ для SQL, способ определения отношений 1-1 и 1-многие с помощью LINQ, способ оптимизации запросов LINQ, выполнение хранимых процедур с помощью LINQ и простой пример CRUD (создание, чтение, обновление, удаление) с использованием LINQ для SQL (Смотрите FAQ часть II)
Что такое LINQ?
LINQ – единая модель программирования для всех видов доступа к данным. LINQ позволяет запрашивать и обрабатывать данные, независимо от источников данных. Ниже рисунок 'LINQ' показывает, как язык .NET контролирует модель программирования LINQ и единообразно работает со всеми видами источников данных. Это походит на язык запросов, способный запросить любой источник данных и любое преобразование. LINQ также обеспечивает полную безопасность типов и проверку во время компиляции.
LINQ может служить в качестве хорошей сущности для среднего уровня. Поэтому он находится между пользовательским интерфейсом и уровнем доступа к данным.
Рисунок - LINQ
Ниже приведен простой пример LINQ. Имеется коллекция данных ‘objcountries’, к которой LINQ делает запрос с названием страны ‘India’. Коллекция ‘objcountries’ может быть любым источником данных: набор данных, считыватель данных, XML, и т.д. Ниже рисунок ‘фрагмент кода LINQ’ показывает, как ‘ObjCountries’ может быть любым контейнером данных. Затем мы запрашиваем ‘CountryCode’ и проходим в цикле по нему же.
Рисунок - фрагмент кода LINQ
Как LINQ помогает с позиции бизнес-объектов?
Одна из нудных задач в бизнес-объектах – разбор и поиск в коллекциях объектов. Например, рассмотрим рисунок ниже, где ищется страна по значению ‘ID’. Мы проходим в цикле по коллекции и получаем объект. Многие спорят насчет хранения ключа в списке или массиве. Ниже показан лишь образец. Например, если вы хотите искать с помощью кода и названия страны, списки/коллекции ключей не будут работать с такими многозначными поисками.
То есть LINQ может запрашивать коллекции бизнес-объектов и проводить выборку из коллекции в одном запросе LINQ.
Можете ли вы объяснить, как выглядит базовый запрос LINQ?
Чтобы понять базовый запрос для LINQ, создадим простой пробный проект. Возьмем данные о клиентах, содержащие клиента и заказы.
Имя клиента |
Код клиента |
Город |
Заказы |
Кхадак |
001 |
Мумбаи |
|
Шив |
002 |
Дели |
|
Раджу |
003 |
Мумбаи |
|
Шаам |
004 |
Дели |
|
Данные усложнены тем, что один клиент имеет несколько заказов, то есть имеется отношение «один ко многим».
Создадим два класса: один – класс «Клиент», объединенный с классом «Коллекция адресов». Ниже показано, как выглядит структура класса, вмещающая в себя отношение «один ко многим» клиента и нескольких адресов.
Несколько адресов являются коллекцией массивов, объединенной внутри класса «Клиент». Ниже приведен фрагмент кода, загружающий коллекции клиентов и адресов с вписанными данными, приведенными в таблице выше. Сейчас они вписаны, но могут загружаться из базы данных или иного источника.
clsCustomer[] objCustomer = new clsCustomer[]
{
new clsCustomer{CustomerName="Khadak",customerCode="001",City="Mumbai",Orders = new clsOrder[]
{new clsOrder{ProductName="Shirt"},
new clsOrder{ProductName="Socks"}}},
new clsCustomer{CustomerName="Shiv",customerCode="002",City="Delhi",Orders = new clsOrder[]{new clsOrder{ProductName="Pants"}}},
new clsCustomer{CustomerName="Raju",customerCode="003",City="Mumbai",Orders = new clsOrder[]{new clsOrder{ProductName="Socks"}}},
new clsCustomer{CustomerName="Shaam",customerCode="004",City="Delhi",Orders = new clsOrder[]{new clsOrder{ProductName="Shoes"}}}};
Базовый запрос LINQ выглядит, как показано ниже. Он начинается с команды from(из), за которой следует тип данных и объект, т.е. объект ‘clsCustomer’ и ‘obj’. ‘objCustomer’ – коллекция, содержащая клиента и адреса, загруженные в верхнем разделе. ‘select obj’ указывает, что нужны все значения.
from clsCustomer obj in objCustomer select obj
В правой части рисунка ниже показан запрос на LINQ. В левой части мы проходим в цикле по коллекции объектов.
Мы создали простой проект, показывающий базовый запрос LINQ; вы можете скачать его, чтобы увидеть его работу. Рисунок ниже показывает выполнение простого запроса.
Как пишется запрос LINQ для поиска с критерием?
Надо поместить условие where(где) перед ключевым словом ‘select(выбрать)’.
return from clsCustomer Obj in objCustomer where Obj.customerCode == “001” select Obj;
Рисунок ниже показывает условие where в действии.
Как выполняется объединение с помощью запроса LINQ?
Ниже приведен фрагмент кода LINQ для создания объединений между коллекциями объектов. В данном случае мы создаем объединение по клиенту и заказам. Если помните, коллекция заказов содержалась в классе «Клиент».
return from clsCustomer ObjCust in objCustomer
from clsOrder ObjOrder in ObjCust.Orders
select ObjCust;
Ниже показано, как выглядит результат выполнения запроса на объединение LINQ.
Как выполняется группировка с помощью запроса LINQ?
Ниже приведен фрагмент кода, показывающий, как запрос group by(сгруппировать по) записан на LINQ. Сначала мы создали временную переменную ‘GroupTemp’, а затем использовали оператор ‘Select’, чтобы вернуть ее же.
var GroupCustomers = from ObjCust in objCustomer
group ObjCust by ObjCust.City into GroupTemp
select new {GroupTemp.Key,GroupTemp};
Рисунок показывает group by в действие.
Как выполняется упорядочивание с помощью запроса LINQ?
Order by (упорядочить по) в LINQ очень прост. Надо лишь вставить order by перед запросом ‘Select’.
return from clsCustomer ObjCust in objCustomer
orderby ObjCust.City
select ObjCust;
Рисунок ниже показывает, как было выполнено упорядочивание по названию города.
Исходный код
Фрагмент кода вышеприведенных запросов можно скачать отсюда.