Expression variables in query expressions (version 3)
An expression variable is considered to be a promoted expression variable, when it's declared in the expression of a second or subsequent from
clause, a let
clause or a where
clause and it's also referenced in one or more following clauses of the same query (but not across an into
clause). Such expression variables are promoted into range variables.
Expression variables are allowed in all query clauses, but they affect how the query is translated only if they are promoted expression variables.
For an expression e
with one or more promoted expression variables v1
, ..., vn
, its expanded form ee
is the anonymous object creation expression fragment eo = e, v1, ... vn
, where eo
is a compiler generated identifier that is invisible and inaccessible, except when mentioned in this section.
The translation for clauses with one or more promoted expression variables is modified as follows:
A query expression with a second from
clause
from x1 in e1
from x2 in e2
...
where e2
contains promoted expression variables is translated into
from * in ( e1 ) . Select ( x1 => new { x1, e2e } )
from x2 in e2o
...
A query expression with a let
clause
from x in e
let y = f
...
where f
contains promoted expression variables v1
, ..., vn
is translated into
from * in ( e ) . Select ( x => new { x , y = f, v1, ..., vn } )
...
A query expression with a where
clause
from x in e
where f
...
where the type of f
is bool
and f
also contains promoted expression variables v1
, ..., vn
is translated into
from * in ( e ) .
Select ( x => f ? new { x, v1, ..., vn } : null ) .
Where ( t => t != null )
...
Here t
is a compiler generated identifier that is otherwise invisible and inaccessible.
A query expression with a where
clause
from x in e
where f
...
where the type of f
is not bool
and f
contains promoted expression variables is translated into
from * in ( e ) . Select ( x => new { x, fe } )
where fo
...
- The
where
clause has different translation when the type of its expression isbool
. This is because the translation used forbool
might not be applicable for other types.
- This specification allows queries like
from o in x where o is Foo foo select foo
. Is that the right way to do it? - The trick of using
null
to representfalse
result is weird, especially for a specification. Is there a better way to do this?