You are on page 1of 20

Putting it all together:

LINQ as an Example

The Problem: SQL in Code


Programs often connect to database servers. Database servers only speak SQL. Programs have to construct SQL strings. PHP example:
if (some_condition()) { $q = mysql_query(select name from user were id = $id) ... }

When will the problem be detected?


2

Searching in Collections
Begin with a simple array of, say, Customers.
Customer[] customers = new Customer[30]; customers[0] = new Customer(); customers[29] = new Customer();

Searching in Collections: The Old Way


Find the names of all London customers:
List<string> londoners = new List<string>(); foreach (Customer c in customers) { if (c.City == London) { londoners.add(c.Name); } }
4

Searching in Collections: The LINQ Way


Returns a simple array!

string[] londoners = from c in customers where c.City == London select c.Name;


No loops! SQL-like!
5

Declarative!

Searching in Collections: The LINQ Way


LINQ is a C# feature
Introduced in C# 3.0.

LINQ = Language INtegrated Query So far, this is just list comprehension added to C#. What did it take to add list comprehension to the language?

LINQ: How Does It Work?


LINQ syntax = shorthand for method invocation. Syntactic sugar, using Translation maps

Syntax Translation Example


string[] londoners = from c in customers where c.City == London select c.Name; string[] londoners = customers. Where(expression). Select(expression);
8

Expressions == Methods?
Where() wants a Boolean method. The method acts as a filter. Likewise for Select(): a translation method.

Translating Expressions
Problem: Translating c.City == London to a boolean expression e, such that Where(e) is valid?

10

C# Delegates
C# delegates: method pointers. Since C# 1.0. class Demo { delegate void Foo(); void Bar() { do something }; void Test() { Foo myDelegate = new Foo(Bar); // pointer to Bar() myDelegate(); // invoke } }

11

Delegates as Arguments
Delegates can be passed as arguments.
Event handlers, jobs for threads, etc.
class Demo { void Job() { the job to carry out }; void Test() { Thread worker = new Thread( new ThreadStart(Job)); worker.start(); } }

12

Anonymous Methods
Nameless methods = on-the-fly delegates:
class Demo { delegate void Foo(); void Test() { Foo myDelegate = delegate() { do something }; myDelegate(); // invoke } }

13

Syntax Translation Example


string[] londoners = from c in customers where c.City == London select c.Name;

string[] londoners = customers. Where(delegate(Customer c) { return c.City == London; }). Select(delegate(Customer c) { return c.Name });
14

Well, Not Really.


Where(), etc. accept delegate methods. But LINQ creates lambda expressions. Seamless conversion via coercion.
15

Syntax Translation Example


string[] londoners = from c in customers where c.City == London select c.Name;

string[] londoners = customers. Where(c => c.City == London). Select(c => c.Name);

16

Lambda Expressions
Lambda expression syntax:
Shades of ML

(argumentList) => expression oneArgument => expression


Arguments optionally typed.
Type inference mechanism. More on that later
17

Wheres Where()?
We invoked Where() on Customers[]. On the resulting Customers[], we invoked Select(). New methods for arrays!?

18

Extension Methods
class Utils { public static firstChar(this string s) { return s.charAt(0); } }

So far, just a simple static method. Can be used like any other.
19

Extension Methods
But now
Using Utils; class Demo { void Foo() { string s = Hello; Console.WriteLine(s.firstChar()); } }

20

Extension Methods
Static methods that seem to extend existing types. Where(), Select(), etc. extend array types in this manner.

21

Query Your Own Types!


LINQ can be applied to any type, not just built-in arrays and lists. Just implement Where(), Select(), etc.

22

LINQ and Relational Data


Lets obtain a DB-table type, and query it.
DbCustomers customers = new DbCustomers(my.mdb); string[] londoners = from c in customers where c.City == London select c.Name;

23

This Makes No Sense!


But Where() applies the filter to every record. on the client! SELECT * FROM CUSTOMERS, and filter with a simple loop!?

24

Back To Lambda Expressions


Lambda expressions can be converted to anonymous methods. Can also be coerced to expression trees.
A run-time representation of the syntax tree.
25

Example
Our code yields:
string[] londoners = customers. Where(c => c.City == London). Select(c => c.Name);

where customers is of type DbCustomers. No DbCustomers.Where(delegate(Customer c)) method exists. However: DbCustomers.Where( Expression<Func<Customer,bool>> xt)
26

What Are Expression Trees?


Any valid expression is converted by the compiler to an expression tree.
a.k.a. the abstract syntax tree of the expression. Normal part of the compilation process, in any language!

Examples: 5+3*2
+ 5 *

c.city == London
== . (dot) 2 c city London

27

Expression Trees
Normally, expression trees only exist at compile-time. In C#, the compiler can create a run-time representation of the expression tree.
The language has a data type for expression trees. Represents lambda expressions at runtime.

Used for generating SQL at runtime.


Guaranteed to be syntactically valid, since it was created from a valid C# expression.
28

Its Just Coercion


So, LINQ converts into expressions that use Where(...), Select(...), etc. For some classes, Where(...) and Select(...) accept delegates; for other classes, they accept expression trees. Lambda expressions can be coerced into either.
29

Projections
Using LINQs select:
from c in customers where c.City == London select new AddressBookEntry(c.Name, c.Phone);

30

Pre-Defined Types Only?


But The projection type (e.g., AddressBookEntry) must be predefined!

31

Ad-Hoc Types
new { [name1 =] expr1,, [ namen =] exprn}

Type implied by types of exprs.


If name is not specified, and expr is either property or x.property, then propertys name will be used.

Example:

from c in customers where c.City == London select new { c.Name, c.Phone };


32

Ad-Hoc Types are Nameless


How do we store the result?
??? q = from select new {};

The ad-hoc type is nameless!

33

Auto-Typed Variables
var x = 7; // x will be of type int var q = from select new {}; // q will be an array of the anonymous type Console.WriteLine(q[0].Name); Local variables only.
No auto-typing for fields or formal parameters.
34

Summary
LINQ adds static SQL expression correctness to C#. To do this, the following features were added to C#:
Lambda expressions. Extension methods. Expression types. List comprehension. Anonymous data types. Type inference.
35

Theres More
There are several LINQ features we did not present here, such as:
Grouping (GROUP BY in SQL) Joins (selecting from multiple tables) ...

These require even more language features, such as closures.


36

What Is Happening to Languages?


As new features are added to programming languages, the languages evolve. Many of the features come from research or experimental languages. Note how many of the new C# features discussed here come from functional languages like ML, Haskell or LISP:
Lambda expressions, expression types, list comprehension, anonymous data types, type inference...
37

Confessions of a Used Programming Language Salesman


An 2007 essay by Eric Meijer (Microsoft). Discusses how features from functional languages slowly creep into mainstream languages. Functional programming has finally reached the masses, except that it is called Visual Basic 9 instead of Haskell 98.
38

A Glimpse Into the Future: LISP (1958)


We have seen the power of representing program source at runtime (expression trees). In LISP, program source can be represented at runtime, but also generated at runtime (or compile-time).
Source code itself is a data structure (a list).

LISP macros are light-years ahead of C/C++ macros.

39

A Glimpse Into the Future: LISP (1958)


50 years later, LISP features are slowly re-appearing in mainstream languages.
e.g., garbage collection, aspect-oriented programming, and more.

Conclusions:
a. Learn from history. b. Know LISP, Haskell, etc: once you really understand them, it will give you serious advantages over ignorant software engineers (even if you never use these languages in practice).
40

You might also like