Нэш Трей - C# 2010. Ускоренный курс для профессионалов (2010) (1160865), страница 143
Текст из файла (страница 143)
Ы)))ьг: язык швтжгрироэаииьтх запросоэ э СВ 2008 для профессиоиалое )ИД "Вильямс", 2008 г.). 534 Глава )б На заметку! Нет причин, по которым нельзя было бы иметь несколько конструкций «оуп внутри запроса, чтобы сразу связать данные из множества разных коллекций. Е предыдущем примере могла существовать коллекция, представляющая языки, на которых говорит каждая нация; тогда можно было бы соединить элементы из коллекции евркагаопа11гаез и коллекции языков. Для этого понадобилось бы поместить еще одну конструкцию «суп сразу за существующей. Конструкция кЬеге и фильтры За одной или более конструкциями Тгов или «о1п, если они есть, обычно размещается одна или более конструкций фильтров.
Фильтры состоят иэ ключевого слова нпеге. за которым следует выражение предиката. Конструкция ипеге транслируется в вызов расширяющего метода ИЬеге с передачей ему предиката как лямбда-выражения. Вызовы ЕпивегаЬ1е. ХЬеге, которые используются при выполнении запроса на типе 1ЕпцвегаЬ1е, преобразуют лямбда-выражение в делегат. И наоборот, вызовы 0оегуаЬ|е. ХЬеге, которые используются, если производится запрос к коллекции через интерфейс ТЯсегуаЬ1е. преобразуют лямбда-выражения в деревья выраженийз. дополнительные сведения о деревьях выражений в Ы)т)я можно найти в разделе "Еще раз о деревьях выражений" далее в главе.
Конструкция огс1е~Ьу Конструкция огс(егЬу используется для сортировки последовательности результатов запроса. Вслед за ключевым словом огс)егЬу идет элемент, по значению которого должна проводиться сортировать; обычно это какое-то свойство переменной диапазона. Сортировку можно выполнять как в возрастающем, так и в убывающем порядке; если не указано ключевое слово аясепс)1пс«или с(еясепс(1пд, то по умолчанию принимается порядок по возрастанию (аясепс)1пс«). После конструкции огс1егЬу можно задавать неограниченный набор подсортировок, разделяя элементы сортировки запятыми, как показано ниже: эягпд Яуятевг ся1пс« Яуясев.11пс(г иззяб Яуясев.оо11есс1опя>эепег1сг риЬ11с с1аяя Евр1оуее ( рсЬ11с астапов ьаясияве ( детг яет; рсЬ11с яггупд еггясиаве ( с«ет! яесг ) риЬ11с ягг1пс« Насгопа11гу ( детг яет! ) ) риЬ11с с1аяя Огс(егвувхавр1е ( ятасгс тога Мягл() ( тат евр1оуеея = пен гьяг<Евр1оуее>() ( пен Евр1оуее ( ьаясиаве = ГЯ1яяяег", Е1гятияве = "Ео", Накгопя11ту = "Авег1сап" В главе 15 было показано, что лямбда-вырвжения.
присвоенные переменным — экземплярам делегата, преобразуются в исполняемый код П., в то время как лямбда-выражения, присвоенные Ехргеяя1оп<Т>, преобразуются в деревья выражений, тем самым описывая выражения с помощью данных, а не исполняемого кода.
В))(е язык интегрированных запросов 535 пен Епр1оуее Ьаясыаве = урирх1п", Рьгякызве = р Зяяуа", Нясзопз111у = укияятап" пен Евр1оуее ( Ьэякыаве = "Бва11я", Р1гзснапе = "Яраи1б1пд", Ияк1опя11ку = "1гьяп" ), пен Еп1р1оуее ( Ьзягняве = "тиапаи", Г1гягнзве = "1ияп", Нак1опаыоу = укияязап" )' изг г)иегу = кгпв епр ьп евр1оуеея огбв*ву еягр.вас1опа11зу, ввр.паяонаве бвзсепб1пд, евр.взгясизякв беясвпбзпд яе1еск евр; 1игеясп( иаг 1сев ьп диету ) ( Оапяо1е.нгзгет Ьпе( "(О), хк(1), тк(2)", Ькеп.ьаяснаве, Ьгев.рьгякыаве, 1сев.ыагзопз11гу ); ) ) Обратите внимание,что поскольку конструкция зе1есг просто возвращает переменную диапазона, это целое выражение запроса является операцией сортировки.
Несомненно, это удобный способ сортировки сущностей в Сз. В данном примере сначала осуществляется сортировка в порядке возрастания по )(зсзопа11с у, затем, во втором выражении в конструкции огбегЬу, результат сортируется по убыванию в каждой группе национальности по Ьзяснзве и, наконец, каждая из этих грутпт сортируется по Е1гягнаве в порядке убывания. Во время компиляции компилятор транслирует первое выражение в конструкции огбегЬу в вызов расширяющего метода ОгбегВу стандартной операции запроса.
Все последующие вторичные выражения сортировки транслируются в цепочку вызовов расширяющих методов ТЬепВу. Если конструкция огбегЬу используется с ключевым словом беясепб1пд, в сгенерированном коде используются вызовы ОгбегвуОеясепб1пд и тпепВуреясепбзпд. Конструкция зе1ес~ и проекция В запросе Ы)т)Я конструкция яе1есс служит для производства конечного результата запроса. Она называется проекпюром, потому что проектирует, или транслирует, данные внутри запроса в форму, удобную для применения. Если в выражении запроса присутствуют фильтрующие конструкции ние ге, ови должны предшествовать ее 1е с с.
Компилятор преобразует конструкцию яе1есг в вызов расширяющего метода яе1есс. тело конструкции зе1есс преобразуется в лямбда-выражение, передаваемое методу ее1есс, который использует его для производства каждого элемента результирующего набора. Анонимные типы здесь чрезвычайно удобны, и вы будете правы, предположив, что средство анонимных типов произошло от операции зе1есс в процессе разработки ЫР)Я.
Чтобы оценить удобство анонимных типов в данном случае, рассмотрим следующий пример: 536 Глава)6 извод Яуягелп изгпд Яувгет.11пдв риа11с с1авя Кези1С ( рихагс Кези1С( гпг гприг, гпг оигриС ) ( 1приС = 1приС; Оисрис = оисрис! ) риЬ1гс гпС 1приС ( деС; вег; ) рив11с гпС Оигриг ( деС; зеС; ) риЬ1гс с1авв Рго)есгог ( згаггс чогб Магп() ( гпС() пиепегв = ( 1, 2, 3, 4 чаг диегу = Егоа х гп пиэпегв яе1есС пее Кеви1С ( х, х*2 ); Рогеасп( чаг 1сет 1п диегу ) Сопво1е.игсге11пе( "1приС = (О), Оиориг = (1)" 1Сеп.1приг, 1Сеп.оиирие )! Приведенный код работает.
Однако посмотрите, как объявлен новый тип кеви1с, предназначенный для сохранения результатов запроса. Что, если в будущем потребуется изменить результат, чтобы он включал х, х*2 и х*32 Сначала придется соответствующим образом модифицировать определение класса кеви1с, что не так-то просто. Намного легче воспользоваться анонимными типами, как показано ниже: изгпд Яузгепп иягпд Яузсет.11пд! риЬ1гс с1азз Рго]ессог ( зиаСгс чо1С паап() ( гпс(] пиеЬегв = ( 1, 2, 3, 4 ); чаг диету = Егоп х 1п пипЬегв зе1есС пеэ ( 1прие х, Оитрие х*2 )) согеасп( чаг 1Сет гп диегу ) Сопво1е.нггие11пе( "1приС = (О), Оигриг = (1)" 1гет.1приС, ага.сигриг ); Вот теперь намного лучше! Теперь можно добавить к результирующему типу новое свойство, назвав его ОигриС2, например, и это не потребует никаких изменений нигде, кроме анонимного типа, экземпляр которого создается внутри выражения запроса.
Существующий код продолжит работать, и любой, кто пожелает использовать новое свойство Оисрис2, сможет это сделать. Конечно, бывают случаи, когда в конструкции ве1есс необходимо использовать предварительно определенные типы, например, когда один из таких типов должен воз- Ь(г(0: язык интегрированных запросов 537 вращаться из функции.
Однако чем чаще будут применяться анонимные типы, тем большая гибкость обеспечится на будущее. Конструкция 1е~ Конструкция 1ес представляет новый локальный идентификатор, на который можно впоследствии ссылаться в остальной части запроса. Думайте о ней как о локальной переменной, видимой только внутри выражения запроса, подобно тому, как обычная локальная переменная в блоке кода видима только внутри этого блока.
Рассмотрим следующий пример: пз1по Яузгеат пз1по Яузсеа.Ь1пх(; пз1пд Яузгеа.со11есс1опз.оепег1с) рив11с с1азз Еар1оуее ( рсЬ11с зег1пч Ьазснаае ( Пест зев; ) роЬ11с згггпс Рггзгнаае ( яес; вест ) ) ривггс с1азз Ьесххаар1е ( зкаг1с чогб Мага() ( чаг еар1оуеез = пен Ь1зк<Еар1оуее>() ( пен Еар1оуее ( Ьазтнате = ьо1аззег", Рггзпнаае = "ЕО" пен Еп|р1оуее ( Ьааснаае = "Рирн1п", Г1гзсиаае = "Чазуа" ) пен Еар1оуее ( Ьазсиате = "Яаа11з", Р1гзсиаае = "Ярап1огпо" ) пен етр1оуее ( Ьазтнаае = "1чапоч", Р1гзгнаае = "1чап" ) )т чаг г(пегу = Егоа еар 1п еар1оуеез 1ее Еи11иааж авр.рагевкана + + аачх.ьазвмааж огоегЪу Еп11иаае зе1есг Еп11наает Еогеаси( чаг 1геа гп т)пеку ) ( Сопзо1е.нггкеьвпе( 1сеа ); ) В приведенном примере нужно отсортировать имена в порядке возрастания, но при этом выполнять сортировку по полному имени, сформированному объединением вместе Рггзгнане и ьазсиаае.
Это объединение реализуется за счет использования конструкции 1ес для определения переменной Еи11напе. Другое замечательное качестволокальныхидентификаторов,создаваемыхконструкцией 1ес, состоит в том,что они ссылаются на коллекции, поэтомутакую переменную можно использовать как входную для другой конструкции Егож чтобы создатьновую производную переменную диапазона.
В разделе "Конструкция Егон и переменные диа- 538 Глава 16 назона" ранее в главе был дан пример применения нескольких конструкций Ягой для генерации таблицы умножения. Ниже показана небольшая вариация этого примера, в которое используется конструкция 1е(п ия1п9 Яуясесп) ияьпч Яуягесп.11пс)) риЬ11с с1аяя Ми1гтаЬ1е ( ясасьс чо1й Ма1п() ( чэг Чиегу = Тгопс х хп ЕписпегаЬ)е.аап9е (О, 10) 1ее 1апехвапде = ВаивехзЬ1е.каппе (О, 10) Рхоа у 1а 1апехкапде яе1есс пез ( Х=х, у=у, Ргосисг = х * У )' ГогеасЬ( чаг асей Тп с(иегу ) ( Сопяо1е.вг1ге01пе( "(О) * (1) = (2)", 1гев.Х, 1 ге п1 .
г, 11ев.ггос)исг ); Изменения, внесенные в первый пример вычисления таблицы умножения, выделены полужирным. Обратите внимание, что был добавлен новый промежуточный идентификатор по имени Тппеграпче и выполнена итерация по коллекции с помощью конструкции ггои. Конструкция д~оир Выражение запроса может иметь необязательную конструкцию Ягоир, которая является мощным средством для разбиения на части входных данных запроса. Конструкция игоир — зто проектор, поскольку проектирует данные в коллекцию интерфейсов 10гоирапд, интерфейс 1ягоир1пи определен в пространстве имен я уз сев.














