LINQ
LINQ Expressions, short for "Language INtegrated Query", provide an elegant SQL-like way to perform query operations on Sequences and collections of data.
This includes ways to filter, sort, group and join sets of data. A LINQ expression always starts with the keyword from
, and its result is always a new Sequence of the same or a derived (and possibly anonymous) type.
In Oxygene, the from
expression can be combined with for
loops using the for each from
shortcut syntax, to combine a query expression with the loop that iterates it.
Please refer to the documentation for from
Expressions in Oxygene and the Standard Query Operators Overview provided by Microsoft for C#, for more details on how to use LINQ
Oxygene, C# and Mercury Languages Only
This topic applies to the Oxygene, C# and Mercury languages only. LINQ is not available in Swift, Java and Go as a language feature (although the Query Expressions methods can be used as regular methods, of course).
LINQ Expressions in Oxygene vs. C# vs. Mercury
In general, Oxygene use the same syntax for LINQ queries as C#, with a few differences.
Oxygene uses with
instead of let
to introduce a new variable:
from o in list with name := o.Name where ...
from o in list let name := o.Name where ...
Oxygene uses a more readable "order by
" for sorting, while C# uses the concatenation "orderby
":
from o in list order by o.name descending
from o in list orderby o.name descending
Oxygene also supports distinct
, reverse
, skip
and take
as LINQ operators, which are not available in C#.
LINQ from Swift, Java and Go
While the Swift, Java and Go languages do not have a language integrated query syntax, the LINQ operators themselevs can still be used using regular lambda/closure syntax:
let sortedAdults = people.Where({ $0.Age > 18 }).OrderBy({ $0.Name })
var sortedAdults = people.Where(p -> p.Age > 18).OrderBy(p -> p.Name);
Queryable Sequences
Depending on the sequence type, LINQ expressions can be processed by the compiler in two ways. For normal sequences, each sub-expression is mapped to simply call to an (extension) method on the sequence, as detailed below. However, for Queryable Sequences, the LINQ expression is converted to meta data that can be interpreted at runtime – for example for translating a LINQ expression directly to an SQL query run against a database.
Mapping
Each LINQ expression maps to an (extension) method on the Sequence type, under the hood. Implementations for these methods are provided by the framework, on .NET, and by the Elements libraries (libToffee, Cooper.jar and Island RTL) on the other platforms.
distinct
– maps to.Distinct()
group X by Y
/group by Y select x
– maps to.GroupBy()
from X in Y
(inner from) – maps to.SelectMany()
with optionalCast<T>
if the type is specified; the result is turned into a special anonymous class where both original and new are available.join on X equals Y
– maps to.Join()
order by X
– maps to.OrderBy
, secondary order to.ThenBy()
order by X descending
– maps to.OrderByDescending
, secondary order to.ThenByDescending()
reverse
– maps to.Reverse()
where X
– maps to.Where()
select X
– maps to.Select()
skip X
– maps to.Skip()
skip while X
– maps to.SkipWhile()
take X
– maps to.Take()
take while X
– maps to.TakeWhile()
with
(Oxygene) andlet
(C#) – maps to.Select()
with a special anonymous that makes both the original and the new variable available.
See Also
from
Expressions in Oxygene- Sequence Types
sequence of
in Oxygene- Standard Query Operators Overview (C#)