Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp Language Specification.doc
Скачиваний:
13
Добавлен:
26.09.2019
Размер:
4.75 Mб
Скачать

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

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

from x in e select x

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

( e ) . Select ( x => x )

В примере

from c in customers select c

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

customers.Select(c => c)

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

7.16.2.4Предложения from, let, where, join и orderby

Выражение запроса с вторым предложением from, за которым следует предложение select,

from x1 in e1 from x2 in e2 select v

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

( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => v )

Выражение запроса с вторым предложением from, за которым следует предложение, отличное от select,

from x1 in e1 from x2 in e2

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

from * in ( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => new { x1 , x2 } ) …

Выражение запроса с продолжением let

from x in e let y = f

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

from * in ( e ) . Select ( x => new { x , y = f } ) …

Выражение запроса с продолжением where

from x in e where f

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

from x in ( e ) . Where ( x => f ) …

Выражение запроса с предложением join без into, за которым следует предложение select,

from x1 in e1 join x2 in e2 on k1 equals k2 select v

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

( e1 ) . Join( e2 , x1 => k1 , x2 => k2 , ( x1 , x2 ) => v )

Выражение запроса с предложением join без into, за которым следуем предложение, отличное от select,

from x1 in e1 join x2 in e2 on k1 equals k2

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

from * in ( e1 ) . Join( e2 , x1 => k1 , x2 => k2 , ( x1 , x2 ) => new { x1 , x2 }) …

Выражение запроса с предложением join и с предложением into, за которым следует предложение select,

from x1 in e1 join x2 in e2 on k1 equals k2 into g select v

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

( e1 ) . GroupJoin( e2 , x1 => k1 , x2 => k2 , ( x1 , g ) => v )

Выражение запроса с предложением join и с предложением into, за которым следует предложение, отличное от select,

from x1 in e1 join x2 in e2 on k1 equals k2 into g

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

from * in ( e1 ) . GroupJoin( e2 , x1 => k1 , x2 => k2 , ( x1 , g ) => new { x1 , g }) …

Выражение запроса с продолжением orderby

from x in e orderby k1 , k2 , … , kn

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

from x in ( e ) . OrderBy ( x => k1 ) . ThenBy ( x => k2 ) . … . ThenBy ( x => kn ) …

Если в предложении упорядочения указывается показатель направления descending, вместо него вызывается оператор OrderByDescending или ThenByDescending.

В следующих переводах предполагается, что в каждом выражении запроса нет предложений let, where, join и orderby, и есть не больше одного начального предложения from.

В примере

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

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

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

В примере

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

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

from * in customers. SelectMany(c => c.Orders, (c,o) => new { c, o }) orderby o.Total descending select new { c.Name, o.OrderID, 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.OrderID, x.o.Total })

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

В примере

from o in orders let t = o.Details.Sum(d => d.UnitPrice * d.Quantity) where t >= 1000 select new { o.OrderID, Total = t }

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

from * in orders. Select(o => new { o, t = o.Details.Sum(d => d.UnitPrice * d.Quantity) }) where t >= 1000 select new { o.OrderID, Total = t }

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

orders. Select(o => new { o, t = o.Details.Sum(d => d.UnitPrice * d.Quantity) }). Where(x => x.t >= 1000). Select(x => new { x.o.OrderID, Total = x.t })

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

В примере

from c in customers join o in orders on c.CustomerID equals o.CustomerID select new { c.Name, o.OrderDate, o.Total }

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

customers.Join(orders, c => c.CustomerID, o => o.CustomerID, (c, o) => new { c.Name, o.OrderDate, o.Total })

В примере

from c in customers join o in orders on c.CustomerID equals o.CustomerID into co let n = co.Count() where n >= 10 select new { c.Name, OrderCount = n }

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

from * in customers. GroupJoin(orders, c => c.CustomerID, o => o.CustomerID, (c, co) => new { c, co }) let n = co.Count() where n >= 10 select new { c.Name, OrderCount = n }

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

customers. GroupJoin(orders, c => c.CustomerID, o => o.CustomerID, (c, co) => new { c, co }). Select(x => new { x, n = x.co.Count() }). Where(y => y.n >= 10). Select(y => new { y.x.c.Name, OrderCount = y.n)

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

В примере

from o in orders orderby o.Customer.Name, o.Total descending select o

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

orders. OrderBy(o => o.Customer.Name). ThenByDescending(o => o.Total)

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]