From Expressions

the from keyword can be used to start a LINQ query against any iterable or queryable sequence. The syntax is:

  var res := from String x in source
    where x.StartsWith('1')
    select x.Length;

The type (String) is optional and is inferred if not provided, else the source values are cast to this type. the identifier defines the identifier to be used for the rest of the linq query and 'source' can be anything as long as it provides methods or extension methods like "Where", "Select", "From", etc, matching the operators.

.NET has built in extension methods for IEnumerable<T> and IQueryable<T>, these can be be activated by adding System.Linq to the using list.

On Java and Cocoa the elements compiler provides a library with the operators to work against the Iterable<T> on Java and INSFastEnumeration<T> on Cocoa, these can be used by adding com.remobjects.elements.linq to the uses on Java, and RemObjects.Elements.Linq on Cocoa.

A linq query has 1 or more linq query operators.

Linq query operators

where

Where can be used to filter a sequence, the expression should return a boolean where true indicates this value will be included in the result.

var tallpeople := from p in people where p.height > 200 select p;

from

From can also be used inside the query itself and can be used to introduce a sub sequence in scope. The syntax is from id in expression, after this both the original identifier and the new id are available in scope.

var chapters :=
  from book in books
  from chapter in book.chapters
  select chapter;
  // returns a sequence of all chapters in all books.

With

With can be used to evaluate a sub expression store it and give it a name so it can be reused in additional queries.

var s := "A sentence";
var vowels := from letter in s
  with let := Char.ToLower(letter)
  where let in ['e', 'u', 'i', 'o', 'a']
  select letter;

join

Join queries can join two seperate collections together. Join queries start with join Type id in source on originalid.member equals id.member, followed with an optional into to change the name of the resulting identifier. The type is optional.

var booksWithAuthor := from b in books
  join a in authors on b.author equals author.id
  select new class (book := b, author = a);

orderby

order by is used to sort a sequence in a specific order. It expects an element value on which it will sort the result and supports multiple sort values, seperated with a comma. An optional asc (default) or desc modifier can be placed after the expression to reverse the order.

var sorted = from x in people order by x.LastName ascending, x.FirstName ascending select x.FirstName +" "+x.LastName;

select

select is followed by an expression and ends up returning a new enumeration of the type of the expression result of this expression, one for each applicable result. When this is not the final query operator in the expression, into has to be used to name the new identifier for the rest of the expression.

  var x := from x in users select x.username into un where un.Length > 4 select un;

group by

group by is used to group a query by an expression, the syntax is:

  var studentsbyage = from st in students
  group st by st.age;

which returns a grouped sequnece with an entry per age with each matching student as a value. When this is not the final query operator in the expression, into has to be used to name the new identifier for the rest of the expression. The identifier after group is implied to be the current linq query identifier if it's omitted.

reverse

reverse the order in which things are returned.

var x := [1,2,3,4,5];
var y := from a in x reverse select a;
// 5,4,3,2,1

distinct

distinct filters the items so no duplicates are ever returned.

var x := [1,2,3,2,4,4,5];
var y := from a in x reverse select a;
// 1,2,3,4,5

take

take takes a limited number of elements from the collection and stops returning after that.

var x := [1,2,3,4,5,6,7];
var y := from a in x take 5 select a;
// 1,2,3,4,5

take while

take while takes the items as long as the expression returns true.

var x := [1,2,3,4,5,6,7];
var y := from a in x take while a < 4 select a;
// 1,2,3

skip

skip skip a number of elements before returning from the collection.

var x := [1,2,3,4,5,6,7];
var y := from a in x skip 3 select a;
// 4,5,6,7

skip while

skip while skips the items as long as the expression returns true.

var x := [1,2,3,4,5,6,7];
var y := from a in x skip while a < 4 select a;
// 4,5,6,7