linq, an introlinq, an intro florin−tudor cristea, microsoft student partner

47
LINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Upload: neil-webster

Post on 11-Jan-2016

217 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

LINQ, An IntroFlorin−Tudor Cristea, Microsoft Student Partner

Page 2: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Hello, LINQ!Because “Hello, world!” is so out of fashion.

Page 3: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Inspiration sources

http://students.info.uaic.ro/ ~alexandru.stefan/ materiale/ LINQ.pdfhttp://linqinaction.nethttp://msdn.microsoft.com/ en-us/ vcsharp/ aa336746.aspx

Page 4: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

LanguageINtegratedQuery

Page 5: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Software is simple. It boils down to two things: code and data. Writing software is not so simple, and one of the major activities it involves is writing code that deals with data.

Page 6: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

LINQ could be the missing link—whether this pun is intended is yet to be discovered—between the data world and the world of general-purpose programming languages.

Page 7: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

LINQ unifies data access, whatever the source of data, and allows mixing data from different kind of sources. It allows for query and set operations, similar to what SQL statements offer for databases.

Page 8: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

LINQ was designed to be used against any type of object or data source and to provide a consistent programming model for doing so.

Page 9: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

http://phplinq.codeplex.com

http://jslinq.codeplex.com

http://quaere.codehaus.org

Page 10: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Once you learn how to use LINQ against an array or a collection, you also know most of the concepts needed to take advantage of LINQ with a database or an XML file.

Page 11: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Programming languages

LINQ building blocks

Expression trees

Query expressions

Standard query

operators

LINQ providersLINQ

to Object

s

Objects

LINQ to XML

XML

LINQ to SQL

RDBMS

LINQ to

DataSet

DataSet

LINQ to

Entities

ADO.NET Entity

Framework

Page 12: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

HelloLINQ.csprojhellolinqworldWords of length 9 beautiful wonderfulWords of length 5 hello worldWords of length 4 linqTotal number of chars is 32 (an average of 6,4 per word)

Page 13: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Hello, um… language enhancements!“How much wood could a woodchuck chuck if a woodchuck could chuck wood?” or what makes LINQ tick.

Page 14: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Implicitly typed local variables, which permit the types of local variables to be inferred from the expressions used to initialize them.

Page 15: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Object initializers, which ease construction and initialization of objects.

Page 16: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Lambda expressions, an evolution of anonymous methods that provides improved type inference and conversion to both delegate types and expression trees.

Page 17: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Extension methods, which make it possible to extend existing types and constructed types with additional methods. With extension methods, types aren’t extended but look as if they were.

Page 18: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Anonymous types, which are types automatically inferred and created from object initializers.

Page 19: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

HelloLE.csproj

HelloLEContd.csproj

ExtensionMethodsDiscoverability.csproj

Page 20: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

LINQ building blocksWarning, headsplosions ahead!

Page 21: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

static void DisplayProcesses(){ var processes = Process.GetProcesses() .Where(process => process.WorkingSet64 > 20*1024*1024) .OrderByDescending(process => process.WorkingSet64) .Select(process => new {

process.Id,

Name=process.ProcessName }); ObjectDumper.Write(processes);}

Page 22: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

sequences query expressions query operators deferred query exec. expression trees

Page 23: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

static void DisplayProcesses(){ var processes = Process.GetProcesses() .Where(process => process.WorkingSet64 > 20*1024*1024) .OrderByDescending(process => process.WorkingSet64) .Select(process => new {

process.Id,

Name=process.ProcessName }); ObjectDumper.Write(processes);}

Page 24: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

The GetProcesses method of the System.Diagnostics.Process class returns an array of Process objects. This is not surprising and probably wouldn’t be interesting, except that arrays implement the generic IEnumerable<T> interface. This interface, which appeared with .NET 2.0, is key to LINQ. In our particular case, an array of Process objects implements IEnumerable<Process>.

Page 25: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

The IEnumerable<T> interface is important because Where, OrderByDescending, Select, and other standard query operators used in LINQ queries expect an object of this type as a parameter.

Page 26: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

public static IEnumerable<TSource> Where<TSource>( this IEnumerable<TSource> source, Func<TSource, Boolean> predicate){ foreach (TSource element in source) { if (predicate(element)) yield return element; }}

// System.Linq.Enumerable

Page 27: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

An iterator is an object that allows you to traverse through a collection’s elements. What is named an iterator in .NET is also known as a generator in other languages such as Python, or sometimes a cursor, especially within the context of a database.

Page 28: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

An iterator is easy to create: it’s simply a method that returns an enumeration and uses yield return to provide the values.

Iterator.csproj

Page 29: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

LINQ queries rely heavily on lazy evaluation (deferred query execution). This is one of the most important concepts in LINQ. Without this facility, LINQ would perform very poorly.

DeferredQueryExecution.csproj

Page 30: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Query operators are not a language extension per se, but an extension to the .NET FCL. Query operators are a set of extension methods that perform operations in the context of LINQ queries. They are the real elements that make LINQ possible.

Page 31: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

static void DisplayProcesses(){ var processes = Process.GetProcesses() .Where(process => process.WorkingSet64 > 20*1024*1024) .OrderByDescending(process => process.WorkingSet64) .Select(process => new {

process.Id,

Name=process.ProcessName }); ObjectDumper.Write(processes);}

Call to Where

Page 32: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

public static IEnumerable<TSource> Where<TSource>( this IEnumerable<TSource> source, Func<TSource, Boolean> predicate){ foreach (TSource element in source) { if (predicate(element)) yield return element; }}

foreach loop

Filter source

Return elements

Page 33: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Some intermediate operations (such as sorting and grouping) do require the entire source be iterated over. Our OrderByDescending call is an example of this.

Page 34: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

We’ve stressed several characteristics of extension methods (Where, etc.):They work on enumerations.They allow pipelined data processing.They rely on delayed execution.All these features make these methods useful to write queries. This explains why these methods are called query operators.

Page 35: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Family Query operators

Filtering OfType, Where

Projection Select, SelectMany

Partitioning Skip, SkipWhile, Take, TakeWhile

Join GroupJoin, Join

Concatenation Concat

Ordering OrderBy, OrderByDescending, Reverse, ThenBy, ThenByDescending

Grouping GroupBy, ToLookup

Set Distinct, Except, Intersect, Union

Conversion AsEnumerable, AsQueryable, Cast, ToArray, ToDictionary, ToList

Equality SequenceEqual

Element

ElementAt, ElementAtOrDefault, First, FirstOrDefault, Last, LastOrDefault, Single, SingleOrDefault

Generation DefaultIfEmpty, Empty, Range, Repeat

Quantifiers All, Any, Contains

Aggregation Aggregate, Average, Count, LongCount, Max, Min, Sum

Page 36: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

var processes = Process.GetProcesses() .Where(process => process.WorkingSet64 > 20*1024*1024) .OrderByDescending(process => process.WorkingSet64) .Select(process => new {

process.Id,

Name=process.ProcessName });

Page 37: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

var processes = from process in Process.GetProcesses() where process.WorkingSet64 > 20*1024*1024 orderby process.WorkingSet64 descending select new { process.Id, Name=process.ProcessName };

Page 38: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

The two code pieces are semantically identical. A query expression is convenient declarative shorthand for code you could write manually. Query expressions allow us to use the power of query operators, but with a query-oriented syntax.

Page 39: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

When you use a query expression, the compiler automagically translates it into calls to standard query operators.

Page 40: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

from id in source

{ from id in source |

join id in source on expr equals

expr [ into id ] |

let id = expr |

where condition |

orderby ordering, ordering, … }

select expr | group expr by key

[ into id query ]

Starts with from

Zero or more from, join, let,

where, or orderby

Ends with select or group byOptional into

continuation

Use let to declare

temporary variables

Page 41: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Query operator C# syntax

All N/A

Any N/A

Average N/A

CastUse an explicitly typed range variable, for example: from int i in numbers

Count N/A

Distinct N/A

GroupBygroup ... bygroup ... by ... into ...

GroupJoinjoin ... in ... on ...equals ... into ...

Joinjoin ... in ... on ...equals ...

LongCount N/A

Max N/A

Min N/A

Page 42: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

Query operator C# syntax

OrderBy orderby

OrderByDescending orderby ... descending

Select select

SelectMany Multiple from clauses

Skip N/A

SkipWhile N/A

Sum N/A

Take N/A

TakeWhile N/A

ThenBy orderby ..., ...

ThenByDescending orderby ..., ... descending

Where where

Page 43: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

var authors = from distinctAuthor in ( from book in SampleData.Books where book.Title.Contains("LINQ") from author in book.Authors.Take(1) select author) .Distinct() select new {distinctAuthor.FirstName, distinctAuthor.LastName};

Page 44: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

var authors = SampleData.Books .Where(book => book.Title.Contains("LINQ")) .SelectMany(book => book.Authors.Take(1)) .Distinct() .Select(author => new {author.FirstName, author.LastName});

Page 45: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

As for expression trees... we’ll cover these later (deferred query execution redux, IQueryable, dynamic queries, abracadabra). Maybe.

Page 46: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

System.Core.dllSystemSystem.LinqSystem.Linq.ExpressionsSystem.Data.DataSetExtensions.dllSystem.DataSystem.Data.Linq.dllSystem.Data.LinqSystem.Data.Linq.MappingSystem.Data.Linq.SqlClientSystem.Xml.Linq.dllSystem.Xml.LinqSystem.Xml.SchemaSystem.Xml.XPath

Page 47: LINQ, An IntroLINQ, An Intro Florin−Tudor Cristea, Microsoft Student Partner

See y’all next time!