Top Banner
Putting it all together: LINQ as an Example
40

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.

Jan 16, 2016

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: 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.

Putting it all together:LINQ as an Example

Page 2: 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.

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

Page 3: 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.

3

Searching in Collections

• Begin with a simple array of, say, Customers.

Customer[] customers = new Customer[30];

customers[0] = new Customer(…);

customers[29] = new Customer(…);

Page 4: 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.

4

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);}

}

Page 5: 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.

5

Searching in Collections:The LINQ Way

string[] londoners =

from c in customers

where c.City == “London”

select c.Name;Declarative!

SQL-like!

No loops!

Returns a simple array!

Page 6: 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.

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?

Page 7: 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.

7

LINQ: How Does It Work?

• LINQ syntax = shorthand for method invocation.

• Syntactic sugar, using “Translation maps”

Page 8: 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.

8

Syntax Translation Example

string[] londoners =

from c in customers

where c.City == “London”

select c.Name;

string[] londoners =

customers.

Where(expression).

Select(expression);

Page 9: 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.

9

Expressions == Methods?

• Where() wants a Boolean method.

• The method acts as a filter.

• Likewise for Select(): a translation method.

Page 10: 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.

10

Translating Expressions

• Problem: Translating

“c.City == “London””

to a boolean expression e, such that Where(e) is valid?

Page 11: 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.

11

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

}}

Page 12: 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.

12

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();}

}

Page 13: 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.

13

Anonymous Methods

• Nameless methods = on-the-fly delegates:

class Demo {delegate void Foo();void Test() {

Foo myDelegate = delegate() { … do something …

}; myDelegate(); // invoke

}}

Page 14: 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.

14

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 });

Page 15: 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.

15

Well, Not Really.

•Where(), etc. accept delegate methods.

• But LINQ creates lambda expressions.

• Seamless conversion via coercion.

Page 16: 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.

16

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);

Page 17: 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.

17

Lambda Expressions

• Lambda expression syntax:

(argumentList) => expressiononeArgument => expression

• Arguments optionally typed.– Type inference mechanism.– More on that later…

Shades of ML…

Page 18: 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.

18

Where’s Where()?

• We invoked Where() on Customers[].

• On the resulting Customers[], we invoked Select().

• New methods for arrays!?

Page 19: 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.

19

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.

Page 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.

20

Extension Methods

• But now…

Using Utils;

class Demo {

void Foo() {

string s = “Hello”;

Console.WriteLine(s.firstChar());

}

}

Page 21: 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.

21

Extension Methods

• Static methods that seem to extend existing types.

• Where(), Select(), etc. extend array types in this manner.

Page 22: 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.

22

Query Your Own Types!

• LINQ can be applied to any type, not just built-in arrays and lists.

• Just implement Where(), Select(), etc.

Page 23: 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.

23

LINQ and Relational Data

• Let’s 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;

Page 24: 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.

24

This Makes No Sense!

• But… Where() applies the filter to every record.

• … on the client!

• SELECT * FROM CUSTOMERS, and filter with a simple loop!?

Page 25: 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.

25

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.

Page 26: 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.

26

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)

Page 27: 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.

27

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 c.city == “London”+

5 *

3 2

==

. (dot) “London”

c city

Page 28: 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.

28

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.

Page 29: 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.

It’s 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

Page 30: 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.

30

Projections

• Using LINQ’s select:

from c in customers

where c.City == “London”

select

new AddressBookEntry(c.Name, c.Phone);

Page 31: 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.

31

Pre-Defined Types Only?

• But…

The projection type (e.g., AddressBookEntry) must be pre-defined!

Page 32: 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.

32

Ad-Hoc Types

• new { [name1 =] expr1,…, [ namen =] exprn}

• Type implied by types of exprs.

• Example:

from c in customerswhere c.City == “London”select new { c.Name, c.Phone };

If name is not specified, and expr is either property or x.property, then property’s

name will be used.

Page 33: 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.

33

Ad-Hoc Types are Nameless

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

• The ad-hoc type is nameless!

Page 34: 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.

34

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 typeConsole.WriteLine(q[0].Name);

• Local variables only.– No auto-typing for fields or formal parameters.

Page 35: 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.

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

Page 36: 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.

There’s 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

Page 37: 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.

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

Page 38: 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.

“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

Page 39: 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.

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

Page 40: 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.

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