Студопедия — 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; просмотров: 434. Нарушение авторских прав; Мы поможем в написании вашей работы!



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

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

Кардиналистский и ординалистский подходы Кардиналистский (количественный подход) к анализу полезности основан на представлении о возможности измерения различных благ в условных единицах полезности...

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

Медицинская документация родильного дома Учетные формы родильного дома № 111/у Индивидуальная карта беременной и родильницы № 113/у Обменная карта родильного дома...

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

Ученые, внесшие большой вклад в развитие науки биологии Краткая история развития биологии. Чарльз Дарвин (1809 -1882)- основной труд « О происхождении видов путем естественного отбора или Сохранение благоприятствующих пород в борьбе за жизнь»...

Гносеологический оптимизм, скептицизм, агностицизм.разновидности агностицизма Позицию Агностицизм защищает и критический реализм. Один из главных представителей этого направления...

Функциональные обязанности медсестры отделения реанимации · Медсестра отделения реанимации обязана осуществлять лечебно-профилактический и гигиенический уход за пациентами...

Определение трудоемкости работ и затрат машинного времени На основании ведомости объемов работ по объекту и норм времени ГЭСН составляется ведомость подсчёта трудоёмкости, затрат машинного времени, потребности в конструкциях, изделиях и материалах (табл...

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