Linq without using query syntax

Digg it! del.icio.us  |  kick it on DotNetKicks.com  |  Stay updated with rss  |  Add to Google


In this post an possibly few upcoming posts, I will be playing with linq without using the query syntax provided by the language. Most of the example/articles
on the linq uses query syntax provided by the language and the keywords like from, where, select etc for working with linq queries. Yes, using the query
syntax is more readable and easy, however, it should be interesting to learn how to work with linq without the syntactic sweetness provided by the C# and
vb.

Defining the data source

For this example, we will use a list of Persons as our data source. We will define the Person class and a private function which will return a populated
List<Person> with some data.

public class Person
{
public Person(int id,string name)
{
 Id=id;
Name=name;
}
public int Id{get;set;}
public string Name{get;set;}
public override string ToString()
{
return string.Format("Id:{0},Name:{1}",this.Id,this.Name);
}
}

The GetData() method follows

private List<Person> GetData()
{
int id=0;
List<Person> list = (from n in new string[] { "niran", "nidheesh", "Stephen", "John" ,"William","Richard"}
 select new Person(++id, n)).ToList();
                                                                                                             return list;
}

The Person class has two properties, Id and Name. The Person class also overrides the ToString() method for returning a readable string describing the person.
We also have created a method which returns a List<Person> populated with some hard coded names. Note: I have used the query syntax for building the List<Person>. However, we will re-write this method at the end of this post without using the query syntax. We will also see how we can avoid the extra id variable for generating the IDs. Here is the full list of persons.

  • Id:1,Name:niran
  • Id:2,Name:nidheesh
  • Id:3,Name:Stephen
  • Id:4,Name:John
  • Id:5,Name:William
  • Id:6,Name:Richard

Selecting all the persons with the odd IDs

List<Person> list = GetData();
List<Person>result = list.Where( x => x%2 == 1).ToList();
PrintList(result);

Result:

  • Id:1,Name:niran
  • Id:3,Name:Stephen
  • Id:5,Name:William

This should print out all the person objects with odd ID contained in the list. Here we call the Where() method which expects a Func<Person,bool> or Func<Person,int,bool>.
We use the first overload Func<Person,bool> and pass it a lambda expression which checks whether the Id of the person in question is odd or not by the
following expression.

x.Id % 2 == 1

Then we call the ToList() method for assigning it to our List variable and send it for printing.

What about sorting?

The below code will print out the persons with an even ID in descending order sorting on their name.

List<Person> list = GetData();
    List<Person> result = list.Where(x => x.Id % 2 == 0)
.OrderByDescending((x)=>x.Name ).ToList();
    PrintList(result);

Result

  • Id:6,Name:Richard
  • Id:2,Name:nidheesh
  • Id:4,Name:John

After filtering the list using Where() method, we call the OrderByDescending() method passing it a Func<Person,string> which returns the key on which we want to sort the list. The OrderByDescending() method is used for sorting in descending order whereas the OrderBy() method is used for sorting in ascending.

Let’s do some projection

Projection means transforming the result of the query into new object. This is what we do when using the select clause of the query syntax. Here we will transform the List<Person> into a List<string> only containing the names of the persons after applying a filter.

List<Person> list = GetData();
List<string> result = list.Where((x)=>x.Name.StartsWith("n",StringComparison.OrdinalIgnoreCase) || x.Name.EndsWith("n",StringComparison.OrdinalIgnoreCase))
.Select((x)=>x.Name).ToList();

Result

  • niran
  • nidheesh
  • Stephen
  • John

Here we are printing names of the persons who’s name either starts with "n" or ends with "n". We first apply the filter and then call the select() method. Here the select() method takes a Func<Person,string> which we provide as the lambda expression.

(x)=>x.Name

The select returns IEnumerable<string> only containing the names.

Rewriting the GetData() method

Below is the new version of the GetData() method. Here we directly call the select() method on the string array containing the names. Also note that we are using a different overload of the select() method which accepts a Func<string,int,Person>. The second int parameter is the index of the element being processed. Since the index is 0 based, we have to add 1 for starting the id from 1.

private List<Person> GetData2()
    {
List<Person> list = new string[] { "niran", "nidheesh", "Stephen", "John" ,"William","Richard"}
.Select((x,id)=>new Person(id+1,x)).ToList();
return list;
    }

Final thoughts

Using the query syntax is certainly the readable and simple solution. However, working with the IEnumerable<t> extension methods like Where, select etc certainly gives us some understanding of the power and the complexity of linq. In the next post I will talk about more complex operations without using the query syntax.

Any suggestion, correction, comments are welcome.


If you liked this post, please subscribe to this blog or kick this story on DotNetKicks.com .

Tags: ,

You can leave a response, or trackback from your own site.

Leave a Reply


© 2008 By Nirandas, All rights reserved.