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
s.OrderBy()
s.Select()
s.Take()
s.Skip()
s.Reverse()
Element Operators
s.First()
s.Last()
s.ElementAt()
Aggregation Operators
s.Count();
s.Min();
Quantifiers (return a bool)
s.Contains()
s.Any()\
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