Monday, January 05, 2009

LINQ with Delphi Prism #1 : Sequences

I have been digging into LINQ this christmas. LINQ is a cool way to query data, whether it is an array, a list or a remote datasource.
LINQ is a new feature of C# 3.0 that comes with Visual Studio 2008, but guess what, Delphi Prism, also supports LINQ all the way.

If you want to play/test LINQ queries syntax you can download and install LinqPad, a free tool to use LINQ querys against a SQL Server database. (You could drop Management Studio for that).

The only disadvantage I found (IMO) on LINQ so far is that quering remote datasources is bound to Microsoft SQL Server database. (Maybe this will be extended in the future)
That involves, the so called "LINQ to SQL" methods, which is, I believe, allready deprecated.

As said before Delphi Prism completely supports LINQ. Starting a 3.5 framework application will give you a reference to System.Linq, the namespace, where LINQ lives.

In this series I will explore LINQ using Delphi Prism:

1. Using LINQ on a sequence
LINQ, in Delphi Prism, works on so called sequences, which is a new type described in the Delphi Prism Wiki as:

Sequences are a special type in the language and can be thought of as a collection of elements, similar to an array.

Declare a sequence like this:

var
Names : sequence
of String :=
[
'Mickey', 'Dick', 'Roland', 'Delphi', 'Harry'];

With LINQ it is very easy to query a collection, like this sequence. You can do this in two ways, namely:
1. Using Lambda expressions
2. Using query comprehension syntax (Query Syntax)


With Lambda expressions you can write rather small expressions to query the data, with the query syntax they become more readable (read less magic ;-)).
By the way the compiler (at least in C#) will translate the query syntax into lambda expressions. Both techniques are complementary. (I think the Oxygene compiler also does this....)


Suppose we want to have all the names from our sequence which have more then 4 characters, containing an "a" and sorted in upper case.


//Using Lambda syntax
var FilteredNames := Names
.Where (n
-> (n.Length >= 4)
and n.Contains('a'))
.OrderBy (n
-> n)
.Select (n
-> n.ToUpper());

//Using query comprehension syntax
var FilteredNames := from n in Names
where ((n.Length
>= 4)
and n.Contains('a'))
order by n
select n.ToUpper;

//Note we don't have to declare FilteredNames

Iterate through the filterednames to show them in a messagebox:

for s : string in FilteredNames do begin
FilteredOnes :
= FilteredOnes + s + "--"
end;

MessageBox.Show(
'FilteredOnes: ' + FilteredOnes)


Note that the original collection, Names in this case, is still holding all the elements.

Conclusion LINQ is a, in basic, simple way to query collections the SQL way. Delphi Prism supports them complete. Choosing Lambda expression or Query syntax will be mostly a personal preference.

2 comments:

Craig said...
This comment has been removed by the author.
Craig said...

LINQ to SQL is incestuous with SQL Server. LINQ to Entities is designed to be multi-DB from the start, and many providers are available for non-SQL Server DBs.