C # 3.0 Language new features (language Specification): 7 query expression

Source: Internet
Author: User
Tags expression final generator implement new features sort
Specification

Original: "C # Version 3.0 Specification", Microsoft
Translation: Lover_p
Query Expression provides a language-integrated syntax for queries that resemble relational and hierarchical query languages, such as SQL and XQuery.

Query-expression:
From-clause Query-body

From-clause:
From From-generators

From-generators:
From-generator
From-generators, From-generator

From-generator:
Identifier in expression

Query-body:
From-or-where-clausesopt orderby-caluseopt Select-or-group-clause into-clauseopt

From-or-where-clauses:
From-or-where-clause
From-or-where-clauses From-or-where-clause

From-or-where-clause:
From-clause
Where-clause

Where-clause:
where boolean-expression

Orderby-clause:
by ordering-clauses

Ordering-clauses:
Ordering-clause
Ordering-clauses, Ordering-clause

Ordering-clause:
Expression ordering-directionopt

Ordering-direction:
Ascending
Descending

Select-or-group-clause:
Select-clause
Group-clause

Select-clause:
SELELCT expression

Group-clause:
Group expression by expression

Into-clause:
into identifier Query-body

A query expression begins with a FROM clause and ends with a select or group clause. The starting FROM clause can be followed by 0 or more from or where clauses. Each FROM clause is a generator that introduces an iteration variable that can overwrite the entire sequence, and each WHERE clause is a filter that is used to expel items from the result. The final Select or group clause specifies the representation of the result based on the iteration variable. The Select or group clause can also precede an ORDER BY clause to specify the sequence of results. Finally, you can use an into clause to "join" two queries by using the result of a query as a generator of a subquery.

In a query expression, a FROM clause with multiple generators is strictly equivalent to a FROM clause that has only one generator in more than one order.

7.1 Translation of query expressions

Instead of specifying the exact execution semantics for a query expression, the C # 3.0 language translates the query expression into a call to a method that is attached to the query expression pattern (Expression). In particular, query expressions are translated into calls to methods named where, Select, SelectMany, order, OrderByDescending, ThenBy, ThenByDescending, and GroupBy, respectively. These methods have the expected signature and return value types. These methods can be either instance methods of the object being queried or an extension method external to the object. These methods carry out the actual query work.

The process of translating a query expression into a method call is a syntax mapping process that occurs before any type binding or overload choice is executed. The results of translation can ensure that the syntax is correct, but not necessarily to produce semantically correct C # code. After the query expression is translated, the resulting method call is processed as a generic method call, and an error is found in turn, such as a method does not exist, a parameter type error, or a type inference failure on a generic method.

The following series of examples, in turn, illustrate the translation of query expressions. A formal description of the translation rules is given in a later section.

7.1.1 WHERE clause

A WHERE clause in the query expression:

From C in Customers

where c.city = "London"

Select C

will be translated as a call to a where method, whose arguments are the lambda expressions that are derived from the merged iteration variable and the expression in the WHERE clause:

Customers.

Where (c => c.city = = "London")

7.1.2 SELECT clause

The above example shows how the SELECT clause that selects the most internal iteration variable is eliminated by translating the method call.

A SELECT clause that selects an iteration variable that is not the most internal:

From C in Customers

where c.city = = "Longdon"

Select C.name

will be translated as a Select method call, whose argument is a lambda expression:

Customers.

Where (c => c.city = = "London").

Select (c => c.name)

7.1.3 Group clause

A group clause:

From C in Customers

Group C.name by C.country

will be translated as a call to the GroupBy method:

Customers.

GroupBy (c => c.country, C => c.name)

7.1.4 BY clause

An by clause:

From C in Customers

by C.name

Select New {c.name, c.phone}

will be translated as a call to the by method, or translated as a call to the OrderByDescending method when the descending indicator is specified:

Customers.

by (c => c.name).

Select (c => new {c.name, c.phone})

Another by clause:

From C in Customers

by C.country, C.balance Descending

Select New {c.name, c.country, c.balance}

will be translated as a call to the ThenBy and ThenByDescending methods:

Customers.

by (c => c.country).

ThenByDescending (c => c.balance).

Select (c => new {c.name, c.country, c.balance})

7.1. More than 5 regeneration builder

Multiple generators:

From C in Customers

where c.city = "London"

From O in C.orders

where o.orderdate.year = = 2005

Select New {c.name, O.orderid, o.total}

will be translated to SelectMany method calls to all non-most internal generators:

Customers.

Where (c => c.city = = "London").

SelectMany (c =>

C.orders.

Where (o => o.orderdate.year = = 2005).

Select (o => new {c.name, O.orderid, o.total})

)

When multiple generators are merged by an by clause:

From C in Customers, O in C.orders

where o.orderdate.year = = 2005

by O.total Descending

Select New {c.name, O.orderid, o.total}

An additional select is injected to collect the sort expression and the final result sequence. It is necessary to allow the order by order to operate the entire sequence. The final result will be extracted after the by:

Customers.

SelectMany (c =>

C.orders.

Where (o => o.orderdate.year = = 2005).

Select (o => new {k1 = o.total, V = new {c.name, O.orderid, O.total}})

).

OrderByDescending (x => x.k1).

Select (x => x.v)

7.1.6 into clause

An INTO clause:

From C in Customers

Group C by C.country into G

Select New {Country = G.key, Custcount = G.group.count ()}

is a very simple form of nested queries:

From G in

From C in Customers

Group C by C.country

Select New {Country = G.key, Custcount = G.group.count ()}

Will be translated as:

Customers.

GroupBy (c => c.country).

Select (g => new {Country = G.key, Custcount = G.group.count ()})

7.2 Query expression pattern

Query expression mode (query Expression pattern) establishes a set of patterns for methods that can be implemented by types to support query expressions. Because the query expression is translated into a method call through a syntax map, the type is particularly flexible in how to implement its query expression pattern. For example, these methods of the pattern can be implemented as instance methods or extension methods because they have exactly the same invocation syntax, and the method's arguments can also be delegate or expression trees because the lambda expression can be converted to both.

The recommended form for generic type c<t> that supports query expression patterns is given below. A generic type is used to demonstrate the correct relationship between a parameter and a result type, or to implement a pattern as a non generic type.

Delegate R Func<a, r> (A Arg);

Class c<t>

{

Public c<t> Where (func<t, bool> predicate);

Public c<s> select<s> (func<t, s> selector);

Public c<s> selectmany<s> (func<t, c<s>> selector);

Public o<t> orderby<k> (func<t, k> keyexpr);

Public o<t> orderbydescending<k> (func<t, k> keyexpr);

Public c<g<k, T>> groupby<k> (func<t, k> keyexpr);

Public c<g<k, E>> groupby<k, e> (func<t, k> keyexpr, func<t, e> elemexpr);

}

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>

{

Public K Key {get;}

Public c<t> Group {get;}

}

The above method uses a generic delegate type Func<a, R>, or an equivalent other delegate or expression tree type, as long as there is a correct relationship between the argument and the result type.

Note that in the relationship between the recommended c<t> and o<t>, make sure that the ThenBy and ThenByDescending methods can only be used on the result of an order by or a orderbydescending. Also note that the recommended form of groupby results should be a set of (anonymous type instance) sequences with key and group attributes.

The standard query operator (Standard query Operators, described in another specification) provides an implementation of a query expression that can be used for all implementations of the System.Collections.Generic.IEnumerable The type of the <T> interface.

7.3 Formal rules of translation

The processing of a query expression applies the following translation rules repeatedly and sequentially. Each translation applies these rules until any given pattern is no longer occurring.

Note that a translation of the call to order and ThenBy will occur, and a call to OrderByDescending or thenbydescending will occur if the corresponding sort clause has a descending indicator.

L A query that contains the INTO clause:

Q1 into X Q2

Will be translated as:

From X in (Q1) Q2

L with multiple generators FROM clause:

From G1, G2, ... gn

Will be translated as:

From G1-from G2-from GN

L immediately follows the FROM clause of the WHERE clause:

From X in E where F

Will be translated as:

From X in (e). Where (x => f)

L A query expression with multiple from clauses, an by clause, and a SELECT clause:

From X1 in E1 to X2 in E2 ... by K1, K2 ... select V

Will be translated as:

(from X1 in E1 to X2 in E2 ...)

Select New {K1 = k1, K2 = K2 ..., v = v})

. By (x => x.k1). ThenBy (x => x.k2) ...

. Select (x => x.v)

L A query expression with multiple from clauses, an by clause, and a group clause:

From X1 in E1 to X2 in E2 ... by K1, K2 ... group V by G

Will be translated as:

(from X1 in E1 to X2 in E2 ...)

Select New {K1 = k1, K2 = K2 ..., v = V, g = g})

. By (x => x.k1). ThenBy (x => x.k2) ...

. GroupBy (x => x.g, x => x.v)

L A query expression with multiple from clauses and a SELECT clause:

From X in E to X1 in E1. Select V

Will be translated as:

(e). SelectMany (x => from X1 in e1 ... select v)

L A query expression with multiple from clauses and a group clause:

From the X in E to X1 in E1 ... group V by G

Will be translated as:

(e). SelectMany (x => from X1 in E1 ... group V by G)

L has a FROM clause, no by clause, and a query expression with a SELECT clause:

From X in e Select V

Will be translated as:

(e). Select (x => v)

When V is the identifier x, the translation is reduced to:

(e)

L has a FROM clause, no by clause, and a query expression with a group clause:

From X in E Group V by G

will be translated into

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

When V is the identifier x, the translation is reduced to:

(e). GroupBy (x => g)

L has a query expression with a FROM clause, an by clause, and a SELECT clause:

From X in e K1, K2. Select V

Will be translated as:

(e). by (x => K1). ThenBy (x => K2) ...

. Select (x => v)

When V is the identifier x, the translation is reduced to:

(e). by (x => K1). ThenBy (x => K2) ...

L has a query expression with a FROM clause, an by clause, and a group clause:

From X to e K1, K2. Group V by G

Will be translated as:

(e). by (x => K1). ThenBy (x => K2) ...

. GroupBy (x => g, x => v)

When V is the identifier x, the translation is reduced to:

(e). by (x => K1). ThenBy (x => K2) ...

. GroupBy (x => g)



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.