This document discusses Language Integrated Query (LINQ) in .NET, including LINQ building blocks, sequences, query operators and expressions, query expression trees, and LINQ to Objects. LINQ allows querying over various data sources like collections, databases, and XML documents using a SQL-like syntax. Query expressions are translated into expression trees which provide optimizations. LINQ to Objects refers to using LINQ directly over IEnumerable collections without an intermediate provider.
4. LINQ Building BlocksLINQ Building Blocks
Software developers spend a lot of time toSoftware developers spend a lot of time to
obtain and manipulate dataobtain and manipulate data
Data can be stored inData can be stored in
CollectionsCollections
DatabasesDatabases
XML documentsXML documents
etc...etc...
As of .NET 3.5 developers can use LINQ – aAs of .NET 3.5 developers can use LINQ – a
simplified approach to data manipulationsimplified approach to data manipulation
4
5. LINQ Building Blocks (2)LINQ Building Blocks (2)
LINQLINQ is a set of extensions to .NET Frameworkis a set of extensions to .NET Framework
Encompasses language-integrated query, set,Encompasses language-integrated query, set,
and transform operationsand transform operations
Consistent manner to obtain and manipulateConsistent manner to obtain and manipulate
"data" in the broad sense of the term"data" in the broad sense of the term
QueryQuery expressionsexpressions can be defined directlycan be defined directly
within the C# programming languagewithin the C# programming language
Used to interact with numerous data typesUsed to interact with numerous data types
Converter toConverter to expression treesexpression trees at compile timeat compile time
and evaluated at runtimeand evaluated at runtime 5
6. LINQ Building Blocks (3)LINQ Building Blocks (3)
LINQ allows query expressions to manipulate:LINQ allows query expressions to manipulate:
Any object implementingAny object implementing IEnumerable<T>IEnumerable<T>
Collections of objectsCollections of objects
RRelational databaseselational databases
XML documentsXML documents
The query expressions are based on numerousThe query expressions are based on numerous
SQL-likeSQL-like query operatorsquery operators
Intentionally designed to look and feel veryIntentionally designed to look and feel very
similar to SQL expressionssimilar to SQL expressions
6
7. LINQ Building Blocks (4)LINQ Building Blocks (4)
"LINQ" is the term used to describe this"LINQ" is the term used to describe this
overall approach to data accessoverall approach to data access
LINQ to ObjectsLINQ to Objects
LINQ over objects implementingLINQ over objects implementing
IEnumerable<T>IEnumerable<T>
LINQ to SQLLINQ to SQL andand LINQ to EntitiesLINQ to Entities implementimplement
LINQ over relational dataLINQ over relational data
LINQ toLINQ to DataSetDataSet is a superset of LINQ to SQLis a superset of LINQ to SQL
LINQ to XMLLINQ to XML is LINQ over XML documentsis LINQ over XML documents
7
8. LINQ to *LINQ to *
8
LINQ enabled data sourcesLINQ enabled data sources
LINQ toLINQ to
ObjectsObjects
ObjectsObjects
LINQLINQ
to XMLto XML
<book>
<title/>
<author/>
<price/>
</book>
<book>
<title/>
<author/>
<price/>
</book>
XMLXML
LINQ enabled ADO.NET
LINQ toLINQ to
DataSetsDataSets
LINQLINQ
to SQLto SQL
LINQ toLINQ to
EntitiesEntities
Relational DataRelational Data
OthersOthers …C#C# VB.NETVB.NET
.NET Language-Integrated Query (LINQ).NET Language-Integrated Query (LINQ)
9. Query OperationsQuery Operations
All LINQ queryAll LINQ query
operations consist ofoperations consist of
three distinct actions:three distinct actions:
1.1. Obtain the dataObtain the data
sourcesource
2.2. Create the queryCreate the query
3.3. Execute the queryExecute the query
9
11. IEnumerable<T>IEnumerable<T>
andand SequencesSequences
The interfaceThe interface IEnumerable<T>IEnumerable<T> is universalis universal
LINQ data sourceLINQ data source
Implemented by arrays and all .NET genericImplemented by arrays and all .NET generic
collectionscollections
Enables enumerating over a collection ofEnables enumerating over a collection of
elementselements
AA sequencesequence in LINQ means a collectionin LINQ means a collection
implementing theimplementing the IEnumerable<T>IEnumerable<T> interfaceinterface
Any variable declared asAny variable declared as IEnumerable<T>IEnumerable<T> forfor
typetype TT is considered a sequence of typeis considered a sequence of type TT
11
12. IEnumerable<T>IEnumerable<T>
andand SequencesSequences (2)(2)
Most of the Standard Query Operators areMost of the Standard Query Operators are
extension methods in the static classextension methods in the static class
System.Linq.EnumerableSystem.Linq.Enumerable
Prototyped with anPrototyped with an IEnumerable<T>IEnumerable<T> as theiras their
first argumentfirst argument
E.g.E.g. Min(IEnumerable<T>)Min(IEnumerable<T>),,
Where(IEnumerable<T>,Where(IEnumerable<T>, Func<T,Func<T, bool>)bool>)
Use theUse the CastCast oror OfTypeOfType operators to performoperators to perform
LINQ queries on legacy,LINQ queries on legacy, non-genericnon-generic .NET.NET
collectionscollections 12
14. LINQ Query ExpressionsLINQ Query Expressions
When you have a collection of data, a commonWhen you have a collection of data, a common
task is to extract a subset of items based on atask is to extract a subset of items based on a
given requirementgiven requirement
You want to obtain only the items with namesYou want to obtain only the items with names
that contain a numberthat contain a number
Or don’t have embedded spacesOr don’t have embedded spaces
LINQ query expressions can greatly simplifyLINQ query expressions can greatly simplify
the processthe process
Query expressions are written in a declarativeQuery expressions are written in a declarative
query syntax introduced in C# 3.0query syntax introduced in C# 3.0
14
15. LINQ Query Expressions (2)LINQ Query Expressions (2)
LINQLINQ query expressionsquery expressions are written in aare written in a
declarative SQL-like syntaxdeclarative SQL-like syntax
Example: extracting a subset of array containingExample: extracting a subset of array containing
items with names of more than 6 characters:items with names of more than 6 characters:
15
string[] games = {"Morrowind", "BioShock", "Daxter",string[] games = {"Morrowind", "BioShock", "Daxter",
"The Darkness", "Half Life", "System Shock 2"};"The Darkness", "Half Life", "System Shock 2"};
IEnumerable<string> subset =IEnumerable<string> subset =
from g in gamesfrom g in games
where g.Length > 6where g.Length > 6
orderby gorderby g
select g;select g;
foreach (string s in subset)foreach (string s in subset)
Console.WriteLine("Item: {0}", s);Console.WriteLine("Item: {0}", s);
17. LINQ Query Expressions (3)LINQ Query Expressions (3)
In LINQ aIn LINQ a queryquery is a basic languageis a basic language
constructionconstruction
Just like classes, methods and delegates in C#Just like classes, methods and delegates in C#
Query expressions are used to query andQuery expressions are used to query and
transform data from any LINQ-enabled datatransform data from any LINQ-enabled data
sourcesource
A LINQ query is not executed untilA LINQ query is not executed until
You iterate over the query resultsYou iterate over the query results
You try to access any of the elements in theYou try to access any of the elements in the
result setresult set 17
18. QueryQuery OOperatorsperators
Query operatorsQuery operators in C# are keywords like:in C# are keywords like:
fromfrom,, inin,, wherewhere,, orderbyorderby,, selectselect, …, …
For each standard query operator aFor each standard query operator a
corresponding extension method existscorresponding extension method exists
E.g.E.g. wherewhere Where(IEnumerable<T>)Where(IEnumerable<T>)
At compile time the C# compiler translatesAt compile time the C# compiler translates
query expressions into expression treesquery expressions into expression trees
Expression treesExpression trees are sequences of method callsare sequences of method calls
(from(from System.Linq.EnumerableSystem.Linq.Enumerable))
18
19. Query Operators – SyntaxQuery Operators – Syntax
The basic syntax of LINQ queries is:The basic syntax of LINQ queries is:
This selects all elements inThis selects all elements in gamesgames data sourcedata source
You can apply criteria by the operatorYou can apply criteria by the operator wherewhere
Any valid C# boolean expression can be usedAny valid C# boolean expression can be used
19
IEnumerable<string> subset =IEnumerable<string> subset =
from g in games select g;from g in games select g;
IEnumerable<string> subset =IEnumerable<string> subset =
from g in gamesfrom g in games
where g.Price < 20where g.Price < 20
select g;select g;
var subset =var subset =
games.Select(g => g);games.Select(g => g);
var subset =var subset =
games.Select(g => g);games.Select(g => g);
var subset =var subset =
games.Select(g => g).games.Select(g => g).
Where(g => g.Price < 20);Where(g => g.Price < 20);
var subset =var subset =
games.Select(g => g).games.Select(g => g).
Where(g => g.Price < 20);Where(g => g.Price < 20);
20. QueryQuery OOperatorsperators (2)(2)
TTwo sets of LINQ standard operatorswo sets of LINQ standard operators
OOperaperatingting onon IEnumerableIEnumerable<<TT>>
OOperaperatingting onon IQueIQuerryableyable<<TT>>
LINQ query operators are shorthand versionsLINQ query operators are shorthand versions
for various extension methodsfor various extension methods
Defined inDefined in System.Linq.EnumerableSystem.Linq.Enumerable typetype
Example:Example:
20
IEnumerable<string> subset =IEnumerable<string> subset =
games.Where(g => g.Price < 20);games.Where(g => g.Price < 20);
var subset =var subset =
from g in gamesfrom g in games
where g.Price < 20where g.Price < 20
select g;select g;
var subset =var subset =
from g in gamesfrom g in games
where g.Price < 20where g.Price < 20
select g;select g;
21. QueryQuery OOperatorsperators (3)(3)
The standard query operators provide queryThe standard query operators provide query
capabilities includingcapabilities including
Filtering –Filtering – wherewhere
Projection –Projection – selectselect,, selectManyselectMany
Aggregation –Aggregation – SumSum,, MaxMax,, CountCount,, AverageAverage
Sorting –Sorting – orderbyorderby
Grouping –Grouping – groupbygroupby
…… and many moreand many more
21
22. SStandardtandard QQueryuery
OOperatorsperators – Example– Example
22
string[] games = {"Morrowind", "BioShock","Half Life",string[] games = {"Morrowind", "BioShock","Half Life",
"The Darkness","Daxter", "System Shock 2"};"The Darkness","Daxter", "System Shock 2"};
// Build a query expression using extension methods// Build a query expression using extension methods
// granted to the Array via the Enumerable type// granted to the Array via the Enumerable type
var subset = games.Where(game => game.Length > 6).var subset = games.Where(game => game.Length > 6).
OrderBy(game => game).Select(game => game);OrderBy(game => game).Select(game => game);
foreach (var game in subset)foreach (var game in subset)
Console.WriteLine(game);Console.WriteLine(game);
Console.WriteLine();Console.WriteLine();
var subset =var subset =
from g in gamesfrom g in games
where g.Length > 6where g.Length > 6
orderby gorderby g
select g;select g;
var subset =var subset =
from g in gamesfrom g in games
where g.Length > 6where g.Length > 6
orderby gorderby g
select g;select g;
25. Query Expression TreesQuery Expression Trees
A queryA query expression treeexpression tree is an efficient datais an efficient data
structure representing a LINQ expressionstructure representing a LINQ expression
Type of abstract syntax tree used for storingType of abstract syntax tree used for storing
parsed expressions from the source codeparsed expressions from the source code
Lambda expressions often translate into queryLambda expressions often translate into query
expression treesexpression trees
IQueryable<T>IQueryable<T> is interface implemented byis interface implemented by
query providers (e.g. LINQ to SQL, LINQ toquery providers (e.g. LINQ to SQL, LINQ to
XML, LINQ to Entities)XML, LINQ to Entities)
IQueryable<T>IQueryable<T> objects use expression treesobjects use expression trees
25
26. Query Expression Trees (2)Query Expression Trees (2)
LINQ queries can be performed over twoLINQ queries can be performed over two
standard .NET interfaces:standard .NET interfaces:
IEnumerable<T>IEnumerable<T>
At compile time IL is emittedAt compile time IL is emitted
IQueryable<T>IQueryable<T>
At compile time a query expression tree isAt compile time a query expression tree is
emittedemitted
Both are evaluated at runtimeBoth are evaluated at runtime
26
27. Query Expression Trees (3)Query Expression Trees (3)
When any element of theWhen any element of the IQueryable<T>IQueryable<T>
result is being accessed for the first timeresult is being accessed for the first time
A query is generated from the expression treeA query is generated from the expression tree
and is executedand is executed
27
int[] nums = new int[] {int[] nums = new int[] {
6, 2, 7, 1, 9, 3 };6, 2, 7, 1, 9, 3 };
var numsLessThanFour =var numsLessThanFour =
from i in numsfrom i in nums
where i < 4where i < 4
select i;select i;
foreach (var item in numsLessThanFour)foreach (var item in numsLessThanFour)
Console.WriteLine(item);Console.WriteLine(item);
Query isQuery is
generated andgenerated and
executed hereexecuted here
Variable is of typeVariable is of type
IQueryable<intIQueryable<int
>>
28. Expression Trees – BenefitsExpression Trees – Benefits
IQueryable<T>IQueryable<T> uses expression trees whichuses expression trees which
provide it mechanisms:provide it mechanisms:
For smart decisions and optimizations whenFor smart decisions and optimizations when
query is generatedquery is generated
Based on analysis of expression treesBased on analysis of expression trees
Optimizing multiple nested or complex queriesOptimizing multiple nested or complex queries
Combining multiple queries into very efficientCombining multiple queries into very efficient
single onesingle one
28
30. LINQ to ObjectsLINQ to Objects
LINQ to ObjectsLINQ to Objects refers to using LINQ queriesrefers to using LINQ queries
directly overdirectly over IEnumerable<TIEnumerable<T>> collectioncollection
Without the an intermediate LINQ provider orWithout the an intermediate LINQ provider or
API, such as LINQ to SQL or LINQ to XMLAPI, such as LINQ to SQL or LINQ to XML
Applicable to any enumerable collectionApplicable to any enumerable collection
The old school data retrieval approachThe old school data retrieval approach
Write complexWrite complex foreachforeach loops that specify howloops that specify how
to retrieve data from a collectionto retrieve data from a collection
ТТhe LINQ approach – write declarative codehe LINQ approach – write declarative code
that describes what to be retrievedthat describes what to be retrieved 30
31. LINQ to Objects – AdvantagesLINQ to Objects – Advantages
LINQ queries offer three main advantages overLINQ queries offer three main advantages over
traditionaltraditional foreachforeach loopsloops
They are more concise and easy-to-readThey are more concise and easy-to-read
Especially when filtering by multiple conditionsEspecially when filtering by multiple conditions
Provide powerful filtering, ordering, andProvide powerful filtering, ordering, and
grouping capabilitiesgrouping capabilities
Can be ported to other data sources with littleCan be ported to other data sources with little
or no modificationor no modification
31
32. LINQ to Objects – ExampleLINQ to Objects – Example
LINQ to ObjectsLINQ to Objects is performing SQL-like queriesis performing SQL-like queries
on in-memory data collections and arrayson in-memory data collections and arrays
32
string[] presidents = { "Adams", "Arthur", "Buchanan",string[] presidents = { "Adams", "Arthur", "Buchanan",
"Bush", "Carter","Cleveland","Clinton", "Coolidge","Bush", "Carter","Cleveland","Clinton", "Coolidge",
"Eisenhower", "Fillmore", "Ford", "Garfield","Grant","Eisenhower", "Fillmore", "Ford", "Garfield","Grant",
"Harding", "Harrison", "Hayes", "Hoover", "Jackson","Harding", "Harrison", "Hayes", "Hoover", "Jackson",
"Jefferson", "Johnson", "Kennedy", "Lincoln","Jefferson", "Johnson", "Kennedy", "Lincoln",
"Madison", "McKinley", "Monroe", "Nixon", "Pierce","Madison", "McKinley", "Monroe", "Nixon", "Pierce",
"Polk", "Reagan", "Roosevelt", "Taft", "Taylor","Polk", "Reagan", "Roosevelt", "Taft", "Taylor",
"Truman", "Tyler", "Van Buren", "Washington","Truman", "Tyler", "Van Buren", "Washington",
"Wilson"};"Wilson"};
string president =string president =
presidents.Where(p => p.StartsWith("Lin")).First();presidents.Where(p => p.StartsWith("Lin")).First();
Console.WriteLine(president);Console.WriteLine(president);
string president =string president =
(from p in presidents(from p in presidents
where p.StartsWith("Lin")where p.StartsWith("Lin")
select p).First();select p).First();
string president =string president =
(from p in presidents(from p in presidents
where p.StartsWith("Lin")where p.StartsWith("Lin")
select p).First();select p).First();
34. Counting the Occurrences ofCounting the Occurrences of
a Word in a String – Examplea Word in a String – Example
34
string text = "Historically, the world of data …";string text = "Historically, the world of data …";
……
string searchTerm = "data";string searchTerm = "data";
string[] source = text.Split(string[] source = text.Split(
new char[] { '.', '?', '!', ' ', ';', ':', ',' },new char[] { '.', '?', '!', ' ', ';', ':', ',' },
StringSplitOptions.RemoveEmptyEntries);StringSplitOptions.RemoveEmptyEntries);
// Use ToLower() to match both "data" and "Data"// Use ToLower() to match both "data" and "Data"
var matchQuery =var matchQuery =
from word in textfrom word in text
where word.ToLower() == searchTerm.ToLower()where word.ToLower() == searchTerm.ToLower()
select word;select word;
int wordCount =int wordCount =
matchQuery.Count();matchQuery.Count();
int wordCount = text.Select(int wordCount = text.Select(
w => w.toLower() ==w => w.toLower() ==
searchTerm.ToLower()).Count();searchTerm.ToLower()).Count();
int wordCount = text.Select(int wordCount = text.Select(
w => w.toLower() ==w => w.toLower() ==
searchTerm.ToLower()).Count();searchTerm.ToLower()).Count();
35. Count the OccurrencesCount the Occurrences
of a Word in a Stringof a Word in a String
Live DemoLive Demo
37. QueryingQuerying CCollectionsollections
What can we query?What can we query?
Not everything can be queried by LINQ toNot everything can be queried by LINQ to
ObjectsObjects
The objects need to be a collectionThe objects need to be a collection
It must implement theIt must implement the IEnumerable<T>IEnumerable<T>
interfaceinterface
The good newsThe good news
Almost all standard collections in .NETAlmost all standard collections in .NET
Framework implementsFramework implements IEnumerable<T>IEnumerable<T>
37
38. QueryingQuerying CCollectionsollections (2)(2)
What can be queried using LINQ to Objects?What can be queried using LINQ to Objects?
Arrays –Arrays – T[]T[]
Generic lists –Generic lists – List<T>List<T>
Generic dictionaries –Generic dictionaries – Dictionary<K,V>Dictionary<K,V>
Strings –Strings – stringstring
Other collections that implementsOther collections that implements
IEnumerable<T>IEnumerable<T>
38
39. Querying ArraysQuerying Arrays
Any kind of arrays can be used with LINQAny kind of arrays can be used with LINQ
Can be even anCan be even an untypeduntyped array of objectsarray of objects
Queries can be applied to arrays of customQueries can be applied to arrays of custom
objectsobjects
Example:Example:
39
Book[] books = {Book[] books = {
new Book { Title="LINQ in Action" },new Book { Title="LINQ in Action" },
new Book { Title="LINQ for Fun" },new Book { Title="LINQ for Fun" },
new Book { Title="Extreme LINQ" } };new Book { Title="Extreme LINQ" } };
var titles = booksvar titles = books
.Where(book => book.Title.Contains("Action")).Where(book => book.Title.Contains("Action"))
.Select(book => book.Title);.Select(book => book.Title);
var titles =var titles =
from b in booksfrom b in books
where b.Title.Contains("Action")where b.Title.Contains("Action")
select b.Title;select b.Title;
var titles =var titles =
from b in booksfrom b in books
where b.Title.Contains("Action")where b.Title.Contains("Action")
select b.Title;select b.Title;
40. Querying Generic ListsQuerying Generic Lists
The previous example can be adapted to workThe previous example can be adapted to work
with a generic listwith a generic list
List<T>List<T>,, LinkedList<T>LinkedList<T>,, Queue<T>Queue<T>,,
Stack<T>Stack<T>,, HashSet<T>HashSet<T>, etc., etc.
40
List<Book> books = new List<Book>() {List<Book> books = new List<Book>() {
new Book { Title="LINQ in Action" },new Book { Title="LINQ in Action" },
new Book { Title="LINQ for Fun" },new Book { Title="LINQ for Fun" },
new Book { Title="Extreme LINQ" } };new Book { Title="Extreme LINQ" } };
var titles = booksvar titles = books
.Where(book => book.Title.Contains("Action")).Where(book => book.Title.Contains("Action"))
.Select(book => book.Title);.Select(book => book.Title);
42. Querying StringsQuerying Strings
AlthoughAlthough System.StringSystem.String may not bemay not be
perceived as a collection at first sightperceived as a collection at first sight
It actually is a collection, because it implementsIt actually is a collection, because it implements
IEnumerable<char>IEnumerable<char>
String objects can be queried with LINQ toString objects can be queried with LINQ to
Objects, like any other collectionObjects, like any other collection
42
var count = "Non-letter characters in this string: 8"var count = "Non-letter characters in this string: 8"
.Where(c => !Char.IsLetter(c)).Where(c => !Char.IsLetter(c))
.Count();.Count();
Console.WriteLine(count);Console.WriteLine(count);
// The result is: 8// The result is: 8
var count =var count =
(from c in "Non-letter…"(from c in "Non-letter…"
where !Char.IsLetter(c)where !Char.IsLetter(c)
select c).Count();select c).Count();
var count =var count =
(from c in "Non-letter…"(from c in "Non-letter…"
where !Char.IsLetter(c)where !Char.IsLetter(c)
select c).Count();select c).Count();
44. Aggregation OperationsAggregation Operations
An aggregation operation computes a singleAn aggregation operation computes a single
value from a collection of valuesvalue from a collection of values
Example of aggregation of field over aExample of aggregation of field over a
sequence of employeessequence of employees
44
NameName SalarySalary
Bay IvanBay Ivan 12500,0012500,00
Bat RamboBat Rambo 13500,0013500,00
Baba YagaBaba Yaga 43300,0043300,00
Kiro the KingKiro the King 29800,0029800,00
Bay MangalBay Mangal 25000,0025000,00
...... ......
MAX(Salary)MAX(Salary)
125500,00125500,00
45. AAggregationggregation MethodsMethods
Average()Average()
Calculates the average value of a collectionCalculates the average value of a collection
Count()Count()
Counts the elements in a collectionCounts the elements in a collection
Max()Max()
Determines the maximum value in a collectionDetermines the maximum value in a collection
Sum()Sum()
Sums the values in a collectionSums the values in a collection
45
46. Aggregation Methods – ExamplesAggregation Methods – Examples
Count(<condition>)Count(<condition>)
Max()Max()
46
double[] temperatures =double[] temperatures =
{28.0, 19.5, 32.3, 33.6, 26.5, 29.7};{28.0, 19.5, 32.3, 33.6, 26.5, 29.7};
int highTempCount = temperatures.Count(p => p > 30);int highTempCount = temperatures.Count(p => p > 30);
Console.WriteLine(highTempCount);Console.WriteLine(highTempCount);
// The result is: 2// The result is: 2
double[] temperatures =double[] temperatures =
{28.0, 19.5, 32.3, 33.6, 26.5, 29.7};{28.0, 19.5, 32.3, 33.6, 26.5, 29.7};
double maxTemp = temperatures.Max();double maxTemp = temperatures.Max();
Console.WriteLine(maxTemp);Console.WriteLine(maxTemp);
// The result is: 33.6// The result is: 33.6
var highTemp =var highTemp =
(from p in temperatures(from p in temperatures
where p > 30where p > 30
select p).Count();select p).Count();
var highTemp =var highTemp =
(from p in temperatures(from p in temperatures
where p > 30where p > 30
select p).Count();select p).Count();
var highTemp =var highTemp =
(from p in temperatures(from p in temperatures
select p).Max();select p).Max();
var highTemp =var highTemp =
(from p in temperatures(from p in temperatures
select p).Max();select p).Max();
47. ProjectionsProjections
ProjectionProjection refers to the act of transforming therefers to the act of transforming the
elements of a collection into a different typeelements of a collection into a different type
The resulting type isThe resulting type is defineddefined by the developerby the developer
Projection operators in LINQProjection operators in LINQ
SelectSelect – projects single values that are based– projects single values that are based
on a transform functionon a transform function
SelectManySelectMany – projects collections of values into– projects collections of values into
a new collection containing all valuesa new collection containing all values
47
48. Projections – ExamplesProjections – Examples
Select(<transform-function))Select(<transform-function))
48
List<string> words =List<string> words =
new List<string>() { "an", "apple", "a", "day" };new List<string>() { "an", "apple", "a", "day" };
var query =var query =
from word in wordsfrom word in words
select word.Substring(0, 1);select word.Substring(0, 1);
foreach (string s in query)foreach (string s in query)
{{
Console.Write("{0} ",s);Console.Write("{0} ",s);
}}
// The result is: a a a d// The result is: a a a d
var query =var query =
words.Select(w =>words.Select(w =>
w.Substring(0,1));w.Substring(0,1));
var query =var query =
words.Select(w =>words.Select(w =>
w.Substring(0,1));w.Substring(0,1));
49. Projections – Examples (2)Projections – Examples (2)
SelectMany(<multi-value-function>)SelectMany(<multi-value-function>)
49
string[] sentence = new string[] {string[] sentence = new string[] {
"The quick brown","The quick brown",
"fox jumped over","fox jumped over",
"the lazy dog"};"the lazy dog"};
// SelectMany returns nine strings// SelectMany returns nine strings
// (sub-iterates the Select result)// (sub-iterates the Select result)
IEnumerable<string> allWords =IEnumerable<string> allWords =
sentence.SelectMany(segment => segment.Split(' '));sentence.SelectMany(segment => segment.Split(' '));
foreach (var word in allWords)foreach (var word in allWords)
Console.WriteLine(" {0}", word);Console.WriteLine(" {0}", word);
// Result: The quick brown fox jumped over the lazy dog// Result: The quick brown fox jumped over the lazy dog
51. ConversionsConversions
Converting a collection to a different typeConverting a collection to a different type
Can change the type of the collectionCan change the type of the collection
Can change the type of the elementsCan change the type of the elements
Conversion operations in LINQ queries areConversion operations in LINQ queries are
useful in a variety of applicationsuseful in a variety of applications
For example:For example:
Enumerable.AsEnumerable<TSourceEnumerable.AsEnumerable<TSource>>
Enumerable.OfType<(TResult)Enumerable.OfType<(TResult)>>
Enumerable.ToArray(TSource)Enumerable.ToArray(TSource)
51
52. CConversiononversion MMethodsethods
If start with "If start with "AsAs""
Change the static type of the source collectionChange the static type of the source collection
but do not enumerate itbut do not enumerate it
If start with "If start with "ToTo""
Enumerate the source collection and turn eachEnumerate the source collection and turn each
item into the corresponding collection typeitem into the corresponding collection type
52
string[] towns =string[] towns =
{"Sofia", "Plovdiv", "Varna", "Bourgas", "Pleven"};{"Sofia", "Plovdiv", "Varna", "Bourgas", "Pleven"};
List<string> list = towns.List<string> list = towns.ToList()ToList();;
53. SortingSorting
A sorting operation orders the elements of aA sorting operation orders the elements of a
sequence based on one or more attributessequence based on one or more attributes
Standard query operatorStandard query operator
OrderBy(…)OrderBy(…)
OrderByDescending(…)OrderByDescending(…)
ThenBy(…)ThenBy(…) – performs a secondary sort in– performs a secondary sort in
ascending orderascending order
ThenByDescending(…)ThenByDescending(…)
Reverse(…)Reverse(…)
53
54. Sorting – ExampleSorting – Example
54
string[] words = { "Bay Kolio", "Pinokio",string[] words = { "Bay Kolio", "Pinokio",
"Dedo Mraz", "Baba Yaga", "Bay Mangal" };"Dedo Mraz", "Baba Yaga", "Bay Mangal" };
IEnumerable<string> query =IEnumerable<string> query =
from word in wordsfrom word in words
orderby word.Length, word.Substring(0, 1) descendingorderby word.Length, word.Substring(0, 1) descending
select word;select word;
foreach (string str in query)foreach (string str in query)
Console.WriteLine(str);Console.WriteLine(str);
/* The result is:/* The result is:
PinokioPinokio
Dedo MrazDedo Mraz
Bay KolioBay Kolio
Baba YagaBaba Yaga
Bay MangalBay Mangal
*/*/
var query =var query =
words.Select(word => word).words.Select(word => word).
OrderBy(word => word.Length).OrderBy(word => word.Length).
ThenByDescending(ThenByDescending(
word => word.Substring(0, 1));word => word.Substring(0, 1));
var query =var query =
words.Select(word => word).words.Select(word => word).
OrderBy(word => word.Length).OrderBy(word => word.Length).
ThenByDescending(ThenByDescending(
word => word.Substring(0, 1));word => word.Substring(0, 1));
55. GroupingGrouping
Operation of putting data into groupsOperation of putting data into groups
The elements in each group share a commonThe elements in each group share a common
value for some attributevalue for some attribute
ExampleExample
55
56. Creating Groups and MapsCreating Groups and Maps
GroupBy()GroupBy()
Groups elements that share a commonGroups elements that share a common
attribute, calledattribute, called keykey
Each group is represented by a sequence ofEach group is represented by a sequence of
IGrouping(TKey,TElement)IGrouping(TKey,TElement) objectsobjects
ToLookup()ToLookup()
InsertsInserts elements into aelements into a Lookup(TKey,Lookup(TKey,
TElement)TElement) based on a key selector functionbased on a key selector function
Distinct()Distinct()
Returns distinct elements form a collectionReturns distinct elements form a collection 56
57. Group By – ExamplesGroup By – Examples
57
var people = new[] {var people = new[] {
new { Name = "Kiki", Town = "Plovdiv"},new { Name = "Kiki", Town = "Plovdiv"},
new { Name = "Pepi", Town = "Sofia"},new { Name = "Pepi", Town = "Sofia"},
new { Name = "Koko", Town = "Sofia"},new { Name = "Koko", Town = "Sofia"},
new { Name = "Mimi", Town = "Plovdiv"}new { Name = "Mimi", Town = "Plovdiv"}
};};
var peopleByTowns =var peopleByTowns =
from p in peoplefrom p in people
group p by p.Town;group p by p.Town;
foreach (var town in peopleByTowns)foreach (var town in peopleByTowns)
{{
Console.Write("Town {0}: ", town.Key);Console.Write("Town {0}: ", town.Key);
foreach (var person in town)foreach (var person in town)
Console.Write("{0} ", person.Name);Console.Write("{0} ", person.Name);
Console.WriteLine();Console.WriteLine();
}}
var peopleByTowns =var peopleByTowns =
people.GroupBy(t => t.Town);people.GroupBy(t => t.Town);
var peopleByTowns =var peopleByTowns =
people.GroupBy(t => t.Town);people.GroupBy(t => t.Town);
58. Group By – Examples (2)Group By – Examples (2)
58
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var numberGroups =var numberGroups =
from n in numbersfrom n in numbers
group n by n % 3;group n by n % 3;
foreach (var g in numberGroups)foreach (var g in numberGroups)
{{
Console.Write("Remainder: {0} -> ", g.Key);Console.Write("Remainder: {0} -> ", g.Key);
foreach (var n in g)foreach (var n in g)
Console.Write("{0} ", n);Console.Write("{0} ", n);
Console.WriteLine();Console.WriteLine();
}}
// Remainder: 2 -> 5 8 2// Remainder: 2 -> 5 8 2
// Remainder: 1 -> 4 1 7// Remainder: 1 -> 4 1 7
// Remainder: 0 -> 3 9 6 0// Remainder: 0 -> 3 9 6 0
var numberGroups =var numberGroups =
numbers.GroupBy(n => n % 3);numbers.GroupBy(n => n % 3);
var numberGroups =var numberGroups =
numbers.GroupBy(n => n % 3);numbers.GroupBy(n => n % 3);
59. JoinsJoins
Action of relating or associating one dataAction of relating or associating one data
source object with a second data source objectsource object with a second data source object
The two data source objects are associatedThe two data source objects are associated
through a common value or attributethrough a common value or attribute
59
60. Join MethodsJoin Methods
JoinJoin
Joins two sequences based on key selectorJoins two sequences based on key selector
functionfunction
And extracts the joined pairs of valuesAnd extracts the joined pairs of values
GroupJoinGroupJoin
Joins two sequences based on key selectorJoins two sequences based on key selector
functionsfunctions
And groups the resulting matches for eachAnd groups the resulting matches for each
elementelement
60
61. Joins – ExampleJoins – Example
61
var owners = new[] {var owners = new[] {
new { Name = "Koko", Town = "Plovdiv"},new { Name = "Koko", Town = "Plovdiv"},
new { Name = "Pepi", Town = "Sofia"},new { Name = "Pepi", Town = "Sofia"},
};};
var pets = new[] {var pets = new[] {
new { Name = "Sharo", Owner = owners[0] },new { Name = "Sharo", Owner = owners[0] },
new { Name = "Rex", Owner = owners[1] },new { Name = "Rex", Owner = owners[1] },
new { Name = "Poohy", Owner = owners[0] },new { Name = "Poohy", Owner = owners[0] },
};};
var petsWithOwners =var petsWithOwners =
from o in ownersfrom o in owners
join p in pets on o.Name equals p.Owner.Namejoin p in pets on o.Name equals p.Owner.Name
select new { Owner = o.Name, Pet = p.Name };select new { Owner = o.Name, Pet = p.Name };
foreach (var p in petsWithOwners)foreach (var p in petsWithOwners)
Console.WriteLine("{0} owned by {1}", p.Pet, p.Owner);Console.WriteLine("{0} owned by {1}", p.Pet, p.Owner);
var petsWithOwners = owners.Join(pets,var petsWithOwners = owners.Join(pets,
(o => o.Name), (p => p.Owner.Name),(o => o.Name), (p => p.Owner.Name),
(o, p) => new {o.Name, p.Name });(o, p) => new {o.Name, p.Name });
var petsWithOwners = owners.Join(pets,var petsWithOwners = owners.Join(pets,
(o => o.Name), (p => p.Owner.Name),(o => o.Name), (p => p.Owner.Name),
(o, p) => new {o.Name, p.Name });(o, p) => new {o.Name, p.Name });
63. Nested QueriesNested Queries
The queries can be nestedThe queries can be nested
For example:For example:
Suppose we have collections ofSuppose we have collections of PersonPerson andand
collections ofcollections of RoleRole objectsobjects
We want get all roles for given person (ID = 1)We want get all roles for given person (ID = 1)
63
var query = peoplevar query = people
.Where(p => p.ID == 1).Where(p => p.ID == 1)
.SelectMany(p => roles.SelectMany(p => roles
.Where(r => r.ID == p.RoleID).Where(r => r.ID == p.RoleID)
.Select(r =>.Select(r =>
new { p.FirstName, p.LastName, r.Role }));new { p.FirstName, p.LastName, r.Role }));