Студопедия — Groupby 1 страница
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Groupby 1 страница






Выражение запроса вида

from x in e group v by k

переводится в

(e). GroupBy (x => k, x => v)

за исключением случая, когда v является идентификатором x, тогда перевод имеет вид

(e). GroupBy (x => k)

В примере

from c in customers
group c.Name by c.Country

переводится в

customers.
GroupBy(c => c.Country, c => c.Name)

7.16.2.7 Прозрачные идентификаторы

При некоторых переводах вставляются переменные диапазона с прозрачными идентификаторами, обозначенными *. Прозрачные идентификаторы не являются правильным языковым средством, они существуют только в виде промежуточного этапа в процессе перевода выражений запросов.

Когда при переводе запроса вставляется прозрачный идентификатор, дальнейшие этапы перевода распространяют прозрачный идентификатор в анонимные функции и анонимные инициализаторы объектов. В таких контекстах прозрачные идентификаторы функционируют следующим образом.

· Когда прозрачный идентификатор является параметром анонимной функции, члены связанного анонимного типа автоматически оказываются в области действия в теле анонимной функции.

· Когда член с прозрачным идентификатором находится в области действия, члены этого члена также находятся в области действия.

· Когда прозрачный идентификатор оказывается в роли декларатора члена в инициализаторе анонимного объекта, он создает член с прозрачным идентификатором.

На этапах перевода, описанных выше, прозрачные идентификаторы всегда создаются вместе с анонимными типами с намерением сохранить несколько переменных диапазона в виде членов одного объекта. В реализации C# для группирования нескольких переменных диапазона можно использовать механизм, отличный от анонимных типов. В следующих примерах перевода предполагается использование анонимных типов и показывается, как при переводе можно избавиться от прозрачных идентификаторов.

В примере

from c in customers
from o in c.Orders
orderby o.Total descending
select new { c.Name, o.Total }

переводится в

from * in customers.
SelectMany(c => c.Orders, (c,o) => new { c, o })
orderby o.Total descending
select new { c.Name, o.Total }

и далее переводится в

customers.
SelectMany(c => c.Orders, (c,o) => new { c, o }).
OrderByDescending(* => o.Total).
Select(* => new { c.Name, o.Total })

что после удаления прозрачных идентификаторов эквивалентно

customers.
SelectMany(c => c.Orders, (c,o) => new { c, o }).
OrderByDescending(x => x.o.Total).
Select(x => new { x.c.Name, x.o.Total })

где x — идентификатор, созданный компилятором, который в других условиях является невидимым и недоступным.

В примере

from c in customers
join o in orders on c.CustomerID equals o.CustomerID
join d in details on o.OrderID equals d.OrderID
join p in products on d.ProductID equals p.ProductID
select new { c.Name, o.OrderDate, p.ProductName }

переводится в

from * in customers.
Join(orders, c => c.CustomerID, o => o.CustomerID,
(c, o) => new { c, o })
join d in details on o.OrderID equals d.OrderID
join p in products on d.ProductID equals p.ProductID
select new { c.Name, o.OrderDate, p.ProductName }

что дальше сокращается до

customers.
Join(orders, c => c.CustomerID, o => o.CustomerID, (c, o) => new { c, o }).
Join(details, * => o.OrderID, d => d.OrderID, (*, d) => new { *, d }).
Join(products, * => d.ProductID, p => p.ProductID, (*, p) => new { *, p }).
Select(* => new { c.Name, o.OrderDate, p.ProductName })

конечный перевод имеет вид

customers.
Join(orders, c => c.CustomerID, o => o.CustomerID,
(c, o) => new { c, o }).
Join(details, x => x.o.OrderID, d => d.OrderID,
(x, d) => new { x, d }).
Join(products, y => y.d.ProductID, p => p.ProductID,
(y, p) => new { y, p }).
Select(z => new { z.y.x.c.Name, z.y.x.o.OrderDate, z.p.ProductName })

где x, y и z — идентификаторы, созданные компилятором, которые в других условиях являются невидимыми и недоступными.

7.16.3 Шаблон выражения запроса

Шаблон выражения запроса задает шаблон методов, которые могут реализовываться в типах для поддержки выражений запросов. Поскольку выражения запросов переводятся в вызовы методов с помощью синтаксического сопоставления, в типах можно реализовывать шаблоны выражений запроса с большой гибкостью. Например, методы шаблона можно реализовать в виде методов экземпляра или методов расширения, потому что они имеют одинаковый синтаксис вызова, а методы могут запрашивать делегаты или деревья выражений, потому что анонимные функции можно преобразовывать в оба типа.

Ниже представлен рекомендуемый формат универсального типа C<T>, который поддерживает шаблон выражения запроса. Универсальный тип используется, чтобы продемонстрировать правильные отношения между параметрами и результирующими типами, но шаблон также можно реализовать и для неуниверсальных типов.

delegate R Func<T1,R>(T1 arg1);

delegate R Func<T1,T2,R>(T1 arg1, T2 arg2);

class C
{
public C<T> Cast<T>();
}

class C<T>: C
{
public C<T> Where(Func<T,bool> predicate);

public C<U> Select<U>(Func<T,U> selector);

public C<V> SelectMany<U,V>(Func<T,C<U>> selector,
Func<T,U,V> resultSelector);

public C<V> Join<U,K,V>(C<U> inner, Func<T,K> outerKeySelector,
Func<U,K> innerKeySelector, Func<T,U,V> resultSelector);

public C<V> GroupJoin<U,K,V>(C<U> inner, Func<T,K> outerKeySelector,
Func<U,K> innerKeySelector, Func<T,C<U>,V> resultSelector);

public O<T> OrderBy<K>(Func<T,K> keySelector);

public O<T> OrderByDescending<K>(Func<T,K> keySelector);

public C<G<K,T>> GroupBy<K>(Func<T,K> keySelector);

public C<G<K,E>> GroupBy<K,E>(Func<T,K> keySelector,
Func<T,E> elementSelector);
}

class O<T>: C<T>
{
public O<T> ThenBy<K>(Func<T,K> keySelector);

public O<T> ThenByDescending<K>(Func<T,K> keySelector);
}

class G<K,T>: C<T>
{
public K Key { get; }
}

В методах выше используются универсальные типы делегатов Func<T1, R> и Func<T1, T2, R>, но в них так же успешно можно было бы использовать другие типы делегатов или деревьев выражений с такими же отношениями между типами параметров и результатов.

Обратите внимание на рекомендуемое отношение между C<T> и O<T>, которое гарантирует, что методы ThenBy и ThenByDescending будут доступны только для результата операторов OrderBy или OrderByDescending. Также обратите внимание на рекомендуемый формат результата оператора GroupBy — последовательность последовательностей, где каждая внутренняя последовательность имеет дополнительное свойство Key.

Пространство имен System.Linq предоставляет реализацию шаблона операторов запроса для любого типа, в котором реализуется интерфейс System.Collections.Generic.IEnumerable<T>.

7.17 Операторы присваивания

Операторы присваивания назначают новое значение переменной, свойству, событию или элементу индексатора.

присваивание:
унарное_выражение оператор_присваивания выражение

оператор_присваивания:
=
+=
-=
*=
/=
%=
&=
|=
^=
<<=
присваивание_со_сдвигом_вправо

Левый операнд присваивания должен быть выражением с классом переменной, доступа к свойству, доступа к индексатору или доступа к событию.

Оператор = называется простым оператором присваивания. Он присваивает значение правого операнда переменной, свойству или элементу индексатора, который представлен левым операндом. Левый операнд оператора простого присваивания не может быть доступом к событию (за исключением случая, описанного в разделе §10.8.1). Простой оператор присваивания описывается в разделе §7.17.1.







Дата добавления: 2015-09-07; просмотров: 428. Нарушение авторских прав; Мы поможем в написании вашей работы!



Композиция из абстрактных геометрических фигур Данная композиция состоит из линий, штриховки, абстрактных геометрических форм...

Важнейшие способы обработки и анализа рядов динамики Не во всех случаях эмпирические данные рядов динамики позволяют определить тенденцию изменения явления во времени...

ТЕОРЕТИЧЕСКАЯ МЕХАНИКА Статика является частью теоретической механики, изучающей условия, при ко­торых тело находится под действием заданной системы сил...

Теория усилителей. Схема Основная масса современных аналоговых и аналого-цифровых электронных устройств выполняется на специализированных микросхемах...

Кран машиниста усл. № 394 – назначение и устройство Кран машиниста условный номер 394 предназначен для управления тормозами поезда...

Приложение Г: Особенности заполнение справки формы ву-45   После выполнения полного опробования тормозов, а так же после сокращенного, если предварительно на станции было произведено полное опробование тормозов состава от стационарной установки с автоматической регистрацией параметров или без...

Измерение следующих дефектов: ползун, выщербина, неравномерный прокат, равномерный прокат, кольцевая выработка, откол обода колеса, тонкий гребень, протёртость средней части оси Величину проката определяют с помощью вертикального движка 2 сухаря 3 шаблона 1 по кругу катания...

Алгоритм выполнения манипуляции Приемы наружного акушерского исследования. Приемы Леопольда – Левицкого. Цель...

ИГРЫ НА ТАКТИЛЬНОЕ ВЗАИМОДЕЙСТВИЕ Методические рекомендации по проведению игр на тактильное взаимодействие...

Реформы П.А.Столыпина Сегодня уже никто не сомневается в том, что экономическая политика П...

Studopedia.info - Студопедия - 2014-2024 год . (0.014 сек.) русская версия | украинская версия