LINQ: Language Integrated Query ST Colloquium, 2008-05-15 Tom - - PowerPoint PPT Presentation

linq language integrated query
SMART_READER_LITE
LIVE PREVIEW

LINQ: Language Integrated Query ST Colloquium, 2008-05-15 Tom - - PowerPoint PPT Presentation

LINQ: Language Integrated Query ST Colloquium, 2008-05-15 Tom Lokhorst Brief example Brief example int[] nrs = {2, 3, 9, 1, 21, 3, 42}; Brief example int[] nrs = {2, 3, 9, 1, 21, 3, 42}; var q = from n in nrs where n < 5 select n * n;


slide-1
SLIDE 1

LINQ: Language Integrated Query

ST Colloquium, 2008-05-15 Tom Lokhorst

slide-2
SLIDE 2

Brief example

slide-3
SLIDE 3

Brief example

int[] nrs = {2, 3, 9, 1, 21, 3, 42};

slide-4
SLIDE 4

Brief example

int[] nrs = {2, 3, 9, 1, 21, 3, 42}; var q = from n in nrs where n < 5 select n * n;

slide-5
SLIDE 5

Brief example

int[] nrs = {2, 3, 9, 1, 21, 3, 42}; var q = from n in nrs where n < 5 select n * n; foreach (var i in q) { Console.WriteLine(i); }

slide-6
SLIDE 6

Brief example

int[] nrs = {2, 3, 9, 1, 21, 3, 42}; var q = from n in nrs where n < 5 select n * n; foreach (var i in q) { Console.WriteLine(i); }

LINQ

slide-7
SLIDE 7

Overview

The problem space LINQ in .NET 3.5 Deconstructing expressions Usages of LINQ Comparisons with other stuff

slide-8
SLIDE 8

Circles, Triangles and Rectangles

slide-9
SLIDE 9

Circles, Triangles and Rectangles

slide-10
SLIDE 10

Circles, Triangles and Rectangles

Business software deals with lots of different types of data: Objects Tree structures (XML) Relational

slide-11
SLIDE 11

Assignment

A web server should show a list of the top 5 memory-intensive processes.

Per process, show its name, and a description. There is a SQL database with descriptions for programs. The list should be in RSS format.

slide-12
SLIDE 12

A bit of History

slide-13
SLIDE 13

A bit of History

.NET 1.0 released early 2002 CLR 1.0, C# 1.0, VB 7 .0 Delegates: managed function pointers

slide-14
SLIDE 14

A bit of History

.NET 1.0 released early 2002 CLR 1.0, C# 1.0, VB 7 .0 Delegates: managed function pointers .NET 2.0 released late 2005 CLR 2.0, C# 2.0, VB 8.0 Generics, iterators, anonymous delegates

slide-15
SLIDE 15

A bit of History

.NET 1.0 released early 2002 CLR 1.0, C# 1.0, VB 7 .0 Delegates: managed function pointers .NET 2.0 released late 2005 CLR 2.0, C# 2.0, VB 8.0 Generics, iterators, anonymous delegates .NET 3.5 released late 2007 CLR 2.0, C# 3.0, VB 9.0 Lambda expressions, local type inferencing, extension methods, LINQ

slide-16
SLIDE 16

LINQ in .NET 3.5

Libraries LINQ to Objects LINQ to XML LINQ to SQL Language enhancements Lambda expressions Query syntax Compiler enhancements Expression trees

slide-17
SLIDE 17

LINQ to Objects

slide-18
SLIDE 18

Eating the sugar

var q = from n in nrs where n < 5 select n * n; int[] nrs = {2, 3, 9, 1, 21, 3, 42}; C# 3.0

slide-19
SLIDE 19

Eating the sugar

IEnumerable<int> q = from n in nrs where n < 5 select n * n; int[] nrs = {2, 3, 9, 1, 21, 3, 42}; C# 3.0

slide-20
SLIDE 20

Eating the sugar

IEnumerable<int> q = nrs.Where<int>(n => n < 5) .Select<int, int>(n => n * n); int[] nrs = {2, 3, 9, 1, 21, 3, 42}; C# 3.0

slide-21
SLIDE 21

Eating the sugar

IEnumerable<float> q = nrs.Where<int>(n => n < 5) .Select<int, float>(n => n * 0.5F); int[] nrs = {2, 3, 9, 1, 21, 3, 42}; C# 3.0

slide-22
SLIDE 22

Eating the sugar

IEnumerable<float> q = Enumerable.Select<int, float>( Enumerable.Where<int>(nrs, n => n < 5), (n => n * 0.5F)); int[] nrs = {2, 3, 9, 1, 21, 3, 42}; C# 3.0

slide-23
SLIDE 23

Eating the sugar

IEnumerable<float> q = Enumerable.Select<int, float>( Enumerable.Where<int>(nrs, n => n < 5), (n => n * 0.5F)); int[] nrs = {2, 3, 9, 1, 21, 3, 42}; C# 3.0 public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate) { ... }

slide-24
SLIDE 24

Eating the sugar

IEnumerable<float> q = Enumerable.Select<int, float>( Enumerable.Where<int>(nrs, n => n < 5), (n => n * 0.5F)); int[] nrs = {2, 3, 9, 1, 21, 3, 42}; C# 3.0 public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate) { foreach (var elem in source) if (predicate(elem)) yield return elem; }

slide-25
SLIDE 25

Eating the sugar

IEnumerable<float> q = Enumerable.Select<int, float>( Enumerable.Where<int>(nrs, n => n < 5), (n => n * 0.5F)); int[] nrs = {2, 3, 9, 1, 21, 3, 42}; C# 3.0

slide-26
SLIDE 26

Eating the sugar

IEnumerable<float> q = Enumerable.Select<int, float>( Enumerable.Where<int>(nrs, delegate(int n){ return n < 5; }), delegate(int n){ return n * 0.5F;} ); int[] nrs = {2, 3, 9, 1, 21, 3, 42}; C# 2.0

slide-27
SLIDE 27

Eating the sugar

IEnumerable<float> q = Enumerable.Select<int, float>( Enumerable.Where<int>(nrs, new Func<int, bool>(LessThanFive)), new Func<int, float>(TimesHalf) ); bool LessThanFive(int n) { return n < 5; } float TimesHalf(int n) { return n * 0.5F; } int[] nrs = {2, 3, 9, 1, 21, 3, 42}; C# 1.0*

slide-28
SLIDE 28

Eating the sugar

var q = from n in nrs where n < 5 select n * n; int[] nrs = {2, 3, 9, 1, 21, 3, 42}; C# 3.0

slide-29
SLIDE 29

LINQ to Objects

Query comprehenssions More syntax; orderby, groupby, join Works on you data structures IEnumerable<T> Implement you own Where<T>, Select<T> More library functions

slide-30
SLIDE 30

LINQ to XML

slide-31
SLIDE 31

Dealing with angle brackets

LINQ to XML is a replacement for the W3C Document Object Model, because: It’ s old It’ s ugly It’ s impractical New API, all library: System.Xml.LINQ

slide-32
SLIDE 32

Document Object Model

Imperative API Document-centric Weird data types

slide-33
SLIDE 33

Document Object Model

Imperative API Document-centric Weird data types

<Company name=”Microsoft”> <Founders> <Person>Bill Gates</Person> </Founders> </Company>

slide-34
SLIDE 34

Document Object Model

XmlDocument doc = new XmlDocument(); XmlElement company = doc.CreateElement("Company"); doc.AppendChild(company); XmlAttribute name = doc.CreateAttribute("name"); name.Value = "Microsoft"; company.Attributes.Append(name); XmlElement founders = doc.CreateElement("Founders"); company.AppendChild(founders); XmlElement person = doc.CreateElement("Person"); founders.AppendChild(person); XmlText bill = doc.CreateTextNode("Bill Gates"); person.AppendChild(bill);

slide-35
SLIDE 35

LINQ to XML

Functional construction Element-centric (context free) CLR data types (collection friendly)

slide-36
SLIDE 36

LINQ to XML

XElement company = new XElement("Company", new XAttribute("name", "Microsoft"), new XElement("Founders", new XElement("Person", "Bill Gates") ) );

Functional construction Element-centric (context free) CLR data types (collection friendly)

slide-37
SLIDE 37

XML with queries

slide-38
SLIDE 38

XML with queries

string[] names = { “Anders”, “Erik”, “Amanda” };

slide-39
SLIDE 39

XML with queries

string[] names = { “Anders”, “Erik”, “Amanda” }; from n in names where n.StartsWith(“A”) select new XElement(“Person”, n)

slide-40
SLIDE 40

XElement employees = new XElement(“Employees”, );

XML with queries

string[] names = { “Anders”, “Erik”, “Amanda” }; from n in names where n.StartsWith(“A”) select new XElement(“Person”, n)

slide-41
SLIDE 41

XElement employees = new XElement(“Employees”, );

XML with queries

string[] names = { “Anders”, “Erik”, “Amanda” }; from n in names where n.StartsWith(“A”) select new XElement(“Person”, n) company.Add(employees);

slide-42
SLIDE 42

XElement employees = new XElement(“Employees”, );

XML with queries

string[] names = { “Anders”, “Erik”, “Amanda” }; from n in names where n.StartsWith(“A”) select new XElement(“Person”, n) company.Add(employees); Console.WriteLine(company);

slide-43
SLIDE 43

XML on the Console

<Company name=”Microsoft”> <Founders> <Person>Bill Gates</Person> </Founders> <Employees> <Person>Anders</Person> <Person>Amanda</Person> </Employees> </Company>

slide-44
SLIDE 44

IEnumerable<string> persons = from p in company.Descendants(“Person”) select p.Value;

Querying XML

slide-45
SLIDE 45

IEnumerable<string> persons = from p in company.Descendants(“Person”) select p.Value;

Querying XML

Bill Gates Anders Amanda

slide-46
SLIDE 46

LINQ to SQL

slide-47
SLIDE 47

Querying a SQL backend

Use LINQ to query a relational database Strongly typed queries Remote the query to the DBMS C# must remain API/DB independent

slide-48
SLIDE 48

LINQ to SQL

Simple Object Relational Mapper Microsoft SQL Server Comes with tool to make classes out of tables in an existing database Certainly not the best ORM out there More advanced stuff: LINQ to Entities

slide-49
SLIDE 49

LINQ to SQL example

slide-50
SLIDE 50

LINQ to SQL example

slide-51
SLIDE 51

LINQ to SQL example

slide-52
SLIDE 52

LINQ to SQL example

[DatabaseAttribute(Name="Northwind")] public partial class NorthwindDataContext : System.Data.LINQ.DataContext { public NorthwindDataContext() : base("Data Source=.;Initial Catalog=Northwind;" + "Integrated Security=True") { } public Table<Customer> Customers { get { return this.GetTable<Customer>(); } } }

slide-53
SLIDE 53

LINQ to SQL example

[Table(Name="dbo.Customers")] public partial class Customer : INotifyPropertyChanging, INotifyPropertyChanged { private string _CustomerID; [Column(Storage="_CustomerID", DbType="NChar(5) NOT NULL", CanBeNull=false, IsPrimaryKey=true)] public string CustomerID { get { return this._CustomerID; } set { /* Setter code removed */ } } /* More code be here */ }

slide-54
SLIDE 54

LINQ to SQL example

slide-55
SLIDE 55

LINQ to SQL example

var db = new NorthwindDataContext(); var q = from c in db.Customers where c.City == “London” select c;

slide-56
SLIDE 56

LINQ to SQL example

var db = new NorthwindDataContext(); var q = from c in db.Customers where c.City == “London” select c; foreach (var c in q) Console.WriteLine(c.CustomerID + “ “ + c.ContactName);

slide-57
SLIDE 57

LINQ to SQL example

var db = new NorthwindDataContext(); var q = from c in db.Customers where c.City == “London” select c; foreach (var c in q) Console.WriteLine(c.CustomerID + “ “ + c.ContactName); AROUT Thomas Hardy BSBEV Victoria Ashworth CONSH Elizabeth Brown EASTC Ann Devon NORTS Simon Crowther SEVES Hari Kumar

slide-58
SLIDE 58

LINQ to SQL example

var q = db.Customers.Where<Customer>( c => c.City == “London”);

slide-59
SLIDE 59

Lambdas again

slide-60
SLIDE 60

Lambdas again

Func<int, int> f = x => (x + 1) * 2; int nr = f(20); Console.WriteLine(nr); // Prints: 42

slide-61
SLIDE 61

Lambdas again

Expression<Func<int, int>> e = x => (x + 1) * 2;

slide-62
SLIDE 62

Lambdas again

string str = e.NodeType + “ “ + e.Parameters.Count; Console.WriteLine(str); // Prints: Lambda 1 Expression<Func<int, int>> e = x => (x + 1) * 2;

slide-63
SLIDE 63

Lambdas again

string str = e.NodeType + “ “ + e.Parameters.Count; Console.WriteLine(str); // Prints: Lambda 1 Expression<Func<int, int>> e = x => (x + 1) * 2; Func<int, int> f = e.Compile(); Console.WriteLine(f(20)); // Prints: 42

slide-64
SLIDE 64

Lambdas again

Expression<Func<int, int>> e = x => (x + 1) * 2;

slide-65
SLIDE 65

Lambdas again

ParameterExpression x = Expression.Parameter(typeof(int), "x"); Expression one = Expression.Constant(1, typeof(int)); Expression two = Expression.Constant(2, typeof(int)); Expression body = Expression.Multiply(Expression.Add(x, one), two); Expression<Func<int, int>> e = Expression.Lambda<Func<int, int>>(body, x); Expression<Func<int, int>> e = x => (x + 1) * 2;

slide-66
SLIDE 66

LINQ to SQL example

var q = db.Customers.Where<Customer>( c => c.City == “London”);

slide-67
SLIDE 67

LINQ to SQL example

ParameterExpression c = Expression.Parameter(typeof(Customer), "c"); IQueryable<Customer> q = db.Customers .Where<Customer>(Expression.Lambda<Func<Customer, bool>>( Expression.Equal( Expression.Property(c, (MethodInfo) methodof(Customer.get_City)), Expression.Constant("London", typeof(string)), false, (MethodInfo) methodof(string.op_Equality)), c));

var q = db.Customers.Where<Customer>( c => c.City == “London”);

slide-68
SLIDE 68

LINQ to SQL example

var q = db.Customers.Where<Customer>( c => c.City == “London”); SELECT C.* FROM Customers AS C WHERE C.City = “London”

slide-69
SLIDE 69

Many more operations

int x = db.Customers.Where<Customer>( c => c.City == “London”).Count(); SELECT COUNT(C.*) AS value FROM Customers AS C WHERE C.City = “London”

slide-70
SLIDE 70

Many more operations

int x = db.Customers.Where<Customer>( c => c.City == “London”).Take(4); SELECT TOP (4) C.* FROM Customers AS C WHERE C.City = “London”

slide-71
SLIDE 71

Many more operations

Restriction Where Projection Select, SelectMany Partitioning Take, Skip, TakeWhile, SkipWhile Join Join, GroupJoin Concatinatin Concat Ordering OrderBy, ThenBy, Reverse Grouping GroupBy Set Distinct, Union, Intersect, Except Conversion ToArray, ToList, ToDictionary, OfType, Cast Elemement First, FirstOrDefault, Last, LastOrDefault Generation Range, Repeat, Empty Quantifiers Any, All, Contains Aggregate Count, Sum, Min, Max, Average, Aggregate

slide-72
SLIDE 72

Assignment

slide-73
SLIDE 73

Assignment

Solution

slide-74
SLIDE 74

Assignment

Solution

new XElement("rss", new XAttribute("version", "2.0"), new XElement("channel", new XElement("title", "Top Processes"), from p in (from p in Process.GetProcesses()

  • rderby p.VirtualMemorySize descending

select p).Take(5) join pd in db.ProcessDescriptions

  • n p.ProcessName equals pd.Name into descrs

from d in descrs.DefaultIfEmpty() select new XElement("item", new XElement("title", p.ProcessName), d != null ? new XElement("description", d.Description) : null) ) );

slide-75
SLIDE 75

Assignment

Solution

<rss version="2.0"> <channel> <title>Top Processes</title> <item> <title>sqlservr</title> <description>SQL Server</description> </item> <item> <title>sqlservr</title> <description>SQL Server</description> </item> <item> <title>devenv</title> <description>Visual Studio</description> </item> <item> <title>ssmsee</title> </item> <item> <title>Reflector</title> </item> </channel> </rss>

slide-76
SLIDE 76

Other providers

DbLinq (MySQL, PostgreSQL, Oracle) LINQ to Google LINQ to Entities Parallel LINQ DryadLINQ (Distributed execution engine)

slide-77
SLIDE 77

Concluding...

All LINQ is: Query comprehensions Libraries Expression trees Many more providers to come...

slide-78
SLIDE 78

Questions?

slide-79
SLIDE 79

Assignment in VB syntax

Dim result = _ <rss version="2.0"> <channel>Top Processes</channel> <%= From p In Process.GetProcesses() _ Order By p.VirtualMemorySize Descending _ Take 5 _ Group Join pd In db.ProcessDescriptions _ On p.ProcessName Equals pd.Name _ Into descrs = Group _ From d In descrs.DefaultIfEmpty _ Select <item> <title><%= p.ProcessName %></title> <%= If(d IsNot Nothing, _ <description><%= d.Description %></description>, _ Nothing) %> </item> %> </rss>

slide-80
SLIDE 80

LINQ in Java

// Setup a JPA entity manager... SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); EntityManagerFactory entityManagerFactory = new EntityManagerFactoryImpl(sessionFactory, PersistenceUnitTransactionType.RESOURCE_LOCAL, true); QueryableEntityManager entityManager = new QueryableEntityManager(entityManagerFactory.createEntityManager()); // Select all customers in the Washington region Iterable<Customer> waCustomers = from("c").in(entityManager.entity(Customer.class)). where(eq("c.getRegion()", "WA")). select("c");

slide-81
SLIDE 81

Monadic parser combinators using C#

public abstract class MiniMLParsers<TInput> : CharParsers<TInput>{ public MiniMLParsers() { Whitespace = Rep(Char(' ').OR(Char('\t').OR(Char('\n')).OR(Char('\r')))); WsChr = chr => Whitespace.AND(Char(chr)); Id = from w in Whitespace from c in Char(char.IsLetter) from cs in Rep(Char(char.IsLetterOrDigit)) select cs.Aggregate(c.ToString(),(acc,ch) => acc+ch); Ident = from s in Id where s != "let" && s != "in" select s; LetId = from s in Id where s == "let" select s; InId = from s in Id where s == "in" select s; Term1 = (from x in Ident select (Term)new VarTerm(x)) .OR( (from u1 in WsChr('(') from t in Term from u2 in WsChr(')') select t)); Term = (from u1 in WsChr('\\') from x in Ident from u2 in WsChr('.') from t in Term select (Term)new LambdaTerm(x,t))

slide-82
SLIDE 82

Monadic parser combinators using C#

from cs in Rep(Char(char.IsLetterOrDigit)) select cs.Aggregate(c.ToString(),(acc,ch) => acc+ch); Ident = from s in Id where s != "let" && s != "in" select s; LetId = from s in Id where s == "let" select s; InId = from s in Id where s == "in" select s; Term1 = (from x in Ident select (Term)new VarTerm(x)) .OR( (from u1 in WsChr('(') from t in Term from u2 in WsChr(')') select t)); Term = (from u1 in WsChr('\\') from x in Ident from u2 in WsChr('.') from t in Term select (Term)new LambdaTerm(x,t)) .OR( (from letid in LetId from x in Ident from u1 in WsChr('=') from t in Term from inid in InId from c in Term select (Term)new LetTerm(x,t,c))) .OR( (from t in Term1 from ts in Rep(Term1) select (Term)new AppTerm(t,ts))); All = from t in Term from u in WsChr(';') select t; }