Below is the link of original article
http://msdn.microsoft.com/en-us/vcsharp/ee906600.aspx
The .NET 4.0 library includes an additional collection class: The SortedSet
SortedSet
In this article we will cover only the querying of in-memory collections.
This article has been  designed to give you a core understanding of LINQ that we will rely heavily on in  subsequent parts of this series.
Before diving into the  code it is essential to define what LINQ actually is. LINQ is not C# 3.0, and vice versa.  LINQ relies heavily on the new  language enhancements introduced in C# 3.0; however, LINQ essentially is the composition of  many standard query operators that allow you to work with data in a more  intuitive way regardless of the data source.
The benefits of using  LINQ are significant – queries are a  first class citizen within the C# language, benefit from compile  time checking of queries, and the ability to debug (step through) queries. We  can expect the next Visual 
The best way to teach new technologies is to just to show you an example and then explain what the heck is going on! – That will be my approach throughout this series; hopefully it is a wise decision.
For our first example we  will compose a query to retrieve all the items in a generic List  collection  (Fig. 1).
private static List<string> people = new List<string>()
{   "Granville", "John", "Rachel", "Betty",   "Chandler", "Ross", "Monica" }; public static void Example1()
{  IEnumerable<string> query = from p in people select p;  foreach (string person in query)   {    Console.WriteLine(person);  }} The code example given in  Fig. 1 is very basic and its functionality could have been replicated easier by  simply enumerating through the items in the List via a foreach loop.
In Fig.1 we compose a  query that will return each of the items in the people List collection by aliasing the  people collection with a variable  p and then selecting  p (p is of type string remember as the  people List is a collection of  immutable  string  objects).
You may notice that query  is of type IEnumerable - this is because we know that  query will hold an enumeration of type string. When we foreach through the query the  GetEnumerator of query is  invoked.
At this time it is beneficial to look at exactly what the compiler generated code looks like (Fig. 2).
public static void Example1()
{  IEnumerable<string> query = people.Select<string, string>(delegate (string p)   {    return p;  });  foreach (string person in query)  {    Console.WriteLine(person);  }} Fig. 2 reveals that our  query has actually been converted by the compiler to use an extension method (in  this case just the Select extension method is used) taking a delegate as its  argument.
You will find that  queries and lambda  expressions  are simply a facade that we deal with in order to make our lives easier – under  the covers the compiler is generating the appropriate code using delegates. Be  aware of this internal compiler behavior!
Also be aware that a  cached anonymous delegate method is generated at compile  time as well (Fig. 3) – we will discuss this particular feature in future  articles.
[CompilerGenerated]private static Func<string, string> <>9__CachedAnonymousMethodDelegate1;
We will now take a look  at a more complex query of the same collection which retrieves a sequence of all  strings in the List whose length is greater than  5(Fig. 4).
public static void Example2()
{  IEnumerable<string> query = from p in people where p.Length > 5   orderby p select p;   foreach (string person in query)   {    Console.WriteLine(person);  }} The example in Fig. 4  relies on the use of two other standard query operators – Where and orderby to achieve the desired  results.
If we examine the code  generated by the compiler for the Example2 method you will see that shown in  Fig. 5 – notice as well that we now have another two cached anonymous  delegate methods (Fig. 6) – each of which  having the type signature of their corresponding delegates (Where delegate and orderby delegate).
public static void Example2()
{  IEnumerable<string> query = people.Where<string>(delegate (string p)   {    return (p.Length > 5);  }).OrderBy<string, string>(delegate (string p)   {    return p;  });  foreach (string person in query)  {    Console.WriteLine(person);  }} [CompilerGenerated]private static Func<string, bool> <>9__CachedAnonymousMethodDelegate4;
[CompilerGenerated]private static Func<string, string> <>9__CachedAnonymousMethodDelegate5;
The type signature of the  Where delegate (Fig. 5) is  Funcdelegate takes a string argument and  returns a bool depending on whether the string was greater than 5 characters in  length. Similarly the orderby delegate (Fig. 5) takes a string argument  and returns a string.
AsEnumerable Operator
I found the AsEnumerable operator to be really important in understanding where the query gets executed, meaning is it going to get converted to SQL and the query would be performed on SQL server or LINQ to objects would be used and query would be performed in memory. The ideal use I have found for AsEnumerable would be when I know that a certain functionality is not available in SQL server, I can perform part of the query using LINQ to SQL (Iqueryable) and the rest executed as LINQ to objects (IEnumerable<T>). Basically, AsEnumerable is a hint to perform this part of the execution using LINQ to objects. This is how the prototype looks:
public static IEnumerable
this IEnumerable
The prototype operates on the source of IEnumerable<T> and also returns an IEnumerable<T>. This is because standard query operators operate on IEnumerable<T>, whereas LINQ to SQL operates on IQueryable<T>, which also happens to implement IEnumerable<T>. So when you execute an operator like on an IQueryable <T> (domain objects), it uses a LINQ to SQL implementation for the where clause. As a result, the query gets executed on SQL Server. But what if we knew in advance that a certain operator would fail on SQL Server since SQL Server has no implementation for it. It's good to use the AsEnumerable operator to tell the query engine to perform this part of the query in memory using LINQ to objects. Let's see an example:
| 
 public static void AsEnumerableExample() { NorthwindDataContext db = new NorthwindDataContext(); var firstproduct = (from product in db.Products where product.Category.CategoryName == "Beverages" select product ).ElementAt(0); Console.WriteLine(firstproduct.ProductName); } 
 | 
When you run this query, it would throw an exception saying that elementat is not supported because SQL Server does not know how to execute elementAt. In this case, when I add as enumerable, the query would execute fine as follows:
| 
 public static void AsEnumerableExample() { NorthwindDataContext db = new NorthwindDataContext(); var firstproduct = (from product in db.Products where product.Category.CategoryName == "Beverages" select product ).AsEnumerable().ElementAt(0); Console.WriteLine(firstproduct.ProductName); } 
 | 
DefaultIfEmpty
The DefaultIfEmpty operator returns a default element if the input sequence is empty. If the input sequence is empty, the DefaultIfEmpty operator returns a sequence with a single element of default (T) which, for reference types, is null. Furthermore, the operator also allows you to specify the default operator that will be returned.
| 
 public static void DefaultIfEmptyExample() { string[] fruits = { "Apple", "pear", "grapes", "orange" }; string banana = fruits.Where(f => f.Equals("Banana")).First(); Console.WriteLine(banana); } 
 | 
The above example throws an exception because the first operator requires that sequence not be empty. Therefore if we were to use defaultifEmpty, this is how it would look:
| 
 public static void DefaultIfEmptyExample1() { string[] fruits = { "Apple", "pear", "grapes", "orange" }; string banana = fruits.Where(f => f.Equals("Banana")).DefaultIfEmpty("Not Found").First(); Console.WriteLine(banana); } 
 | 
Another interesting use of DefaultIfEmpty is to perform a left outer join using GroupJoin. Here is an example that illustrates that:
| 
 public class Category { public string CategoryName { get; set; } } public class Product { public string ProductName { get; set; } public string CategoryName { get; set; } } 
 public static void LeftOuterJoin() { Category[] categories = { new Category{CategoryName="Beverages"}, new Category{CategoryName="Condiments"}, new Category{CategoryName="Dairy Products"}, new Category{CategoryName="Grains/Cereals"} }; Product[] products = { new Product{ProductName="Chai", CategoryName="Beverages"}, new Product{ProductName="Northwoods Cranberry Sauce", CategoryName="Condiments"}, new Product{ProductName="Butter", CategoryName="Dairy Products"}, }; var prodcategory = categories.GroupJoin( products, c => c.CategoryName, p => p.CategoryName, (category, prodcat) => prodcat.DefaultIfEmpty() .Select(pc => new { category.CategoryName, ProductName = pc != null ? pc.ProductName : "No" }) ).SelectMany(s => s); 
 foreach (var product in prodcategory) { Console.WriteLine("Category :{0}, Product = {1}", product.CategoryName, product.ProductName); } } 
 | 
In the example above, I am using left outer join to list all categories, regardless of whether they have any products or not.
The order operator allows collections to be ordered using orderby, orderbydescending, thenby and thenbydescending. Here is what the prototype looks like:
public static IOrderedEnumerableOrderBy ( 
this IEnumerablesource, 
Func keySelector) whereK : IComparable The operator takes an IEnumerable<T> and orders the collection based on the key selector that will return the key value for each element in the sequence. The only important point that is worth mentioning is that the sorting of orderby and orderbydescending is considered unstable, meaning that if two elements return the same key based on the key selector, the order of the output could be the maintained or could be different. You should never rely on the order of elements coming out of an orderby call other than the field specified in the orderby clause. 
Another interesting point that I found was that orderby, orderbydescending and orderbyascending take as an input source IEnumerable
|  public static void OrderByOperators()     {        Book[] books =        {            new Book{Title="ASP.NET 2.0 Website Programming: Problem -Design - Solution",                 Author="Marco Bellinaso"},            new Book{Title="ASP.NET 2.0 Unleashed", Author="Stephen Walther"},            new Book{Title="Pro ASP.NET 3.5 in C# 2008,  Second Edition",                Author="MacDonald and Mario Szpuszta"},            new Book{Title="ASP.NET 3.5 Unleashed ", Author="Stephen Walther"},        };        IEnumerable              books.OrderBy(b => b.Author).ThenBy(b => b.Title);     }  | 
In the above example, I make use of both orderby and thenby. Since orderby only works on IEnumerable<T>, I make use of the thenby extension method as well. The second prototype for orderby takes in Icomparable and does not require the return type of the keyselector delegate to return a Collection that implements IComparable. Here is what the prototype looks like:
public static IOrderedEnumerableOrderBy ( 
this IEnumerablesource, 
Func keySelector, IComparer comparer); interface IComparer{ 
int Compare(T x, T y);
}  The compare method will return a greater int if the second argument is greater than the first, equal to zero if both arguments are equal and less than zero if the first argument is less than the second. Let's see an example of that:
|  public class LengthComparer : IComparer {    public int Compare(string title1,  string title2)    {        if (title1.Length < class="code-keyword">return -1;        else if (title1.Length > title2.Length) return 1;        else return 0;    }}  | 
I have created a custom comparer which compares the book title based on the title's length. When the length of the first title is less than the second title's length, I return -1. If it's greater, I return 1. Otherwise, I return 0 for being equal. This is how I make use of the comparer in my LINQ query.
| 
 public static void OrderByUsingCustomComparer()     {        Book[] books =        {            new Book{Title="ASP.NET 2.0 Website Programming: Problem -Design - Solution",                 Author="Marco Bellinaso"},            new Book{Title="ASP.NET 2.0 Unleashed", Author="Stephen Walther"},            new Book{Title="Pro ASP.NET 3.5 in C# 2008,  Second Edition",                Author="MacDonald and Mario Szpuszta"},            new Book{Title="ASP.NET 3.5 Unleashed ", Author="Stephen Walther"},        };        IEnumerable            new LengthComparer());    }
 |