>Query or method syntax

>

There are a series of “Query Keywords” which most of them should be familiar to any VFP developer. They are very similar to the SQL clauses we are familiar with and results they provide are more or less similar. Beside query keywords, there are a series of extension methods defined in Linq namespace with same or similar names to those keywords and more. As said before you can use query syntax most of the time and need to use method syntax in some cases where query syntax is not supported. That is what language supports and forces you to do. IMHO however, method syntax is easier and nicer. Once you get a hang of it, query syntax and the SQL we know sounds to be a hard language:) I will try to go with both syntaxes but might honor method syntax more.

To understand the method syntax and to use it effectively we need to learn how to read method signature. Here are the signatures of System.Linq.Enumerable.Where method as an example:

public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)

public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, int, bool> predicate
)

Syntax is not easy to understand but don’t be afraid. If you can rewrite it in your mind unofficially you can understand it quicker then you expect:

  • There are 2 signatures or two ‘overloads’ of Where method, meaning it could be called with 2 parameter sets.
  • <TSource> : Is all about generic typing. In case of <Customer> all those TSource become Customer type.
  • public static IEnumerable<TSource> : read this part as “it would return a series of records” – TSource is the type of Object. Think it like a table. If table is Customers then TSource is a Customers row where fields are its properties.
  • Input parameters are (for first overload):
  1. this IEnumerable<TSource> source : Parameter name is “source” and it is a collection of TSource objects (think Customer as sample). “this” tells you that it is an extension method and can be used on “this” instance (of Customer type) just like as VFP’s “this”.
  2. Func<TSource, bool> predicate : Parameter name is predicate and it is an inline method (a lambda expression) that takes an object of type TSource (say Customer) as input and returns a bool result (true or false).

    In second overload, second parameter is –

  3. Func<TSource, int, bool> predicate : Parameter name is again “predicate”, which is an inline method that takes an object type of TSource, plus an integer as input parameters and returns a boolean value.

Lets recap it in a pseudo code and a little bit VFP like typing:

procedure Where( source as CollectionOfTSource ) as CollectionOfTSource

Loop and call predicate( TSource ) per item in source Collection

Add those that returns True to return Set

Procedure predicate( item as TSource ) as Logical

in second overload procedure named “predicate” would look like:

Procedure predicate( item as TSource, parameter2 as integer ) as Logical

Let’s give an example to understand better:

int[] numbers = {1,10,29,5,53,33,32,277,232,32,43};

IEnumerable<int> oddNumbers = from n in numbers where n % 2 != 0 select n;

oddNumbers.Dump(“Odd numbers using query syntax”);

This is vanilla ice query syntax that looks like an SQL and correspond to first overload of Where() method. Here we use “where” clause with a simple filter. Same query can be done with method syntax like this:

IEnumerable<int> odds = System.Linq.Enumerable.Where( numbers,n => n % 2 != 0 );

odds.Dump(“Odd numbers using method syntax – 1”);

We are sending “numbers” as ( IEnumerable<TSource> source ) parameter and ” n => n % 2 != 0 ” as ( Func<TSource, bool> predicate ) parameter to Where() method defined in System.Linq.Enumerable class. TSource is defined as int in this case. Since “Where” method is defined as an extension method for IEnumerable<TSource> (in other words a collection of same type of objects – their type is referred to as TSource, in our sample TSource is int to remind) we could use the Where method directly on the collection instance (our collection here is “numbers” which is a collection of int). Here is our simplified version:

IEnumerable<int> odds2 = numbers.Where( n => n % 2 != 0 );

odds2.Dump(“Odd numbers using method syntax – 2”);

// Could write those 2 lines as one – didn’t do like that just to prevent confusion:

// numbers.Where( n => n % 2 != 0 ).Dump(“Odd number using method syntax – 2”);

Method syntax is easier IMHO and moreover it lets us to use the second overload of Where(). In second overload “int” parameter is an index to item’s location (in forums you should have seen questions like: “how can I get last 3 orders per customer”, this parameter lets you go further and in your inline method you can have criteria for the position – not supported on all Linq flavors, i.e.: Linq to SQL doesn’t support it). Let’s use it in our next sample to select odd numbers from our set “where” the number’s position in array is greater than 3rd element and less than 6th element (remember in C# sequences start at 0):

numbers.Where( (n, i) => n % 2 != 0 && i > 2 && i < 5 ).Dump(“Odd numbers from a subset”);

Note that we didn’t do any sorting (yet) last query would return 5,53. Play with simple queries using Where() method to get used to it, you wouldn’t regret you learned method syntax (especially when you see chained multiple methods which we don’t see in SQL). You can mix query and method syntax. By the way, whatever syntax you use intellisense kicks in and helps you on the way.

PS: n => n % 2 != 0 is a lambda expression and is typed (actually its type name is LambdaExpression). Typed > has a type (class) > is reusable, can be saved, loaded, passed around as a parameter (not something that we see with SQL and for that reason I think hard to understand initially).

About cetinbasoz

A developer working primarily with C#,F#,VFP,SQL server, Silverlight,Linq ...
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s