38. var slowQuery =
from c in customers
from p in purchases where c.ID == p.CustomerID
select c.Name + " bought a " + p.Description;
var fastQuery =
from c in customers
join p in purchases on c.ID equals p.CustomerID
select c.Name + " bought a " + p.Description;
39.
40. var easyToRead =
from c in customers
join p in purchases on c.ID equals p.CustomerID
select c.Name + " bought a " + p.Description;
var harderToRead = customers.Join (
purchases,
c => (int?)(c.ID),
p => p.CustomerID,
(c, p) => ((c.Name + " bought a ") +
p.Description)
);
C# 2 introduced generics, at that point, C# is feature complete from an OO perspective
Next challenge to tackle after OO features is Big Data, how to reduce complexity of integrating information
Have to juggle translation between database constructs and objects
Easy way to query data source
Extension methods, query comprehension syntax
Way to return arbitrary results
Anonymous types, var keyword
Way to pass input data
Closures, collection and object initializers
May be too complicated to know at design time, but known at compile time. For more flexibility, you need dynamics and the DLR in .NET 4.
For the last piece of the puzzle, let’s talk about variable binding
System.Void isn’t a true Type
Image: http://www.efunda.com/math/bessel/images/BesselJPlot.gif
Need a separate generic delegate for void return methods
Image: http://portcityfilmfestival.com/clap-board.jpg
Distill down to simpler forms, all equivalent
Image: http://watermarked.cutcaster.com/cutcaster-photo-100783484-Lambda-symbol-in-glass-3d.jpg
The term lambdas comes from lambda calculus. Instead of set-based theories like Venn diagrams, Church wanted to look at it from a functional design perspective.
Take the number 5
I could express that as a function that always returns 5
This is more like Church’s notation
In an operation like adding, I can substitute the functions for the numbers
If I can do that, adding itself can be defined as a function.
Adding has no side effects. 5 is still 5 after I use it while adding.
If you take this to its logical conclusion, any group of operations can be expressed as a hierarchy of functions – which C# calls Expression Trees.
But if that’s true, it makes sense that I can write some function-by-function transformations that turn a C# function into a SQL function…
With a provider of transformations, I can take queries in C# and turn them into queries against a bunch of different data sources. .NET ships with a few, but you can write others.
Now to the practical side of things….
Here, I use LINQPad (http://linqpad.com) to demonstrate Where and the like.
Map or Project is a functional-language based description of the operation. We call it Select because of most C# programmers’ “SQL heritage”.
Select can take a position argument. Many LINQ operators have overloads, check them out.
Zip can replace simple Join statements.
Like fibers in a thread, binding with SelectMany takes many sets and combines them into one.
With Select, this would look like { {Andy’s orders}, {Beth’s orders}, {Charlie’s orders}…}
With SelectMany, this would look like { Andy1, Andy2, Beth1, Charlie1, Charlie2…}
SelectMany is like doing a cross join in SQL, whereas Join is an inner join
Easy to Read is query comprehension syntax. It came from the Entity Framework folks that were also working on this data query problem.
Hard to Read is extension methods.
Skip and Take allow you to “page” through your data. There’s also SkipWhile and TakeWhile.
Examples include Count(), Sum()…
Here, I show the Aggregate command.
Included in .NET 4.5 or can be downloaded as an external library in .NET 4
Use ToParallel() to invoke PLINQ