Saturday, July 4, 2015

C# in Nutshell Chapter 8 - LINQ


A query operator never alters the input sequence; instead, it returns a new sequence. This is consistent with the functional programming paradigm, from which LINQ was inspired.

string[] s = {"Dirk", "Xi", "Auli", "Jouni"};
IEnumerable<string> items = s.where (n => n.length >=4);

Sequence Operators 

Element Operators

Aggregation Operators

Quantifiers (return a bool)

Other Operators

int[] seq1 = { 1, 2, 3 };
int[] seq2 = { 3, 4, 5 };
IEnumerable<int> concat = seq1.Concat (seq2); // { 1, 2, 3, 3, 4, 5 }
IEnumerable<int> union = seq1.Union (seq2); // { 1, 2, 3, 4, 5 }

Query Expression

Query expressions always start with a from clause and end with either a select or
group clause. The from clause declares a range variable (in this case, n), which you
can think of as traversing the input sequence—rather like foreach.

IEnumerable<string> query =
from n in names
where n.Contains ("a") // Filter elements
orderby n.Length // Sort elements
select n.ToUpper(); // Translate each element (project)

The Into Keyword

The into keyword lets you “continue” a query after a projection and is a shortcut
for progressively querying.
The only place you can use into is after a select or group clause. into “restarts” a
query, allowing you to introduce fresh where, orderby, and select clauses.

IEnumerable<string> query =
from n in names
select n.Replace ("a", "").Replace ("e", "").Replace ("i", "")
.Replace ("o", "").Replace ("u", "")
into noVowel
where noVowel.Length > 2 orderby noVowel select noVowel;

Otherwise, we need to write

IEnumerable<string> query =
from n in names
select n.Replace ("a", "").Replace ("e", "").Replace ("i", "")
.Replace ("o", "").Replace ("u", "");
query = from n in query where n.Length > 2 orderby n select n;

Scoping rules
All range variables are out of scope following an into keyword. The following will not compile:
var query =
from n1 in names
select n1.ToUpper()
into n2 // Only n2 is visible from here on.
where n1.Contains ("x") // Illegal: n1 is not in scope.
select n2;

Projection Strategies

Object Initializers

class TempProjectionItem
public string Original; // Original name
public string Vowelless; // Vowel-stripped name

string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };

IEnumerable<TempProjectionItem> temp =
from n in names select new TempProjectionItem
Original = n,
Vowelless = n.Replace ("a", "").Replace ("e", "").Replace ("i", "")
.Replace ("o", "").Replace ("u", "")

Anonymous Types
We can eliminate the TempProjectionItem class in our previous
example with anonymous types:

var intermediate = from n in names
select new
Original = n,
Vowelless = n.Replace ("a", "").Replace ("e", "").Replace ("i", "")
.Replace ("o", "").Replace ("u", "")
IEnumerable<string> query = from item in intermediate
where item.Vowelless.Length > 2
select item.Original;

Let Keyword

string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };
IEnumerable<string> query =
from n in names
let vowelless = n.Replace ("a", "").Replace ("e", "").Replace ("i", "") .Replace ("o", "").Replace ("u", "")
where vowelless.Length > 2 orderby vowelless
select n; // Thanks to let, n is still in scope.

Interpreted Queries

LINQ provides two parallel architectures: local queries for local object collections, and interpreted queries for remote data sources.

Interpreted queries operate over sequences that implement IQueryable<T>.

combined interpreted and local queries

No comments:

Post a Comment