Tuesday, August 16, 2011

LINQ: OfType Query Operator?


LINQ comes with the OfType<T> query operator, through which we can filter the required object type from a heterogeneous array.

Suppose below is the scenario where we have array with various types but will only retrieve the string type. Here we go with ease of life,


using System;
using System.Collections.Generic;
using System.Text;
using System.Query;
using System.Xml.XLinq;
using System.Data.DLinq;

namespace LINQConsoleApplication1_Oct11
{
    class Program
    {
        static void Main(string[] args)
        {
            object[] numbers = {"Wriju", 28, 12/12/2006, 3.3f, 1, "Tupur", 8.0};
            var strs = numbers.OfType<string>();

            Console.WriteLine("The list of friends..");
            Console.WriteLine("==========================");

            foreach(var s in strs)
            {
                Console.WriteLine(s);
            }
            Console.ReadKey();
        }
    }
}

Output will look like

The list of friends..
==========================
Wriju
Tupur

What are Expression Trees?

Expression tree is the construct that has been developed for remote LINQ model. In a nutshell expression trees provide a separation layer between data source and run time. With the help of avisitor pattern expression tree is interpreted in run time and query object is translated into the presentation that is understandable to the data source. In case of LINQ-to-SQL, expression trees are translated into SQL with column names mapped from XML configuration. The SQL query is sent to the database and the result undergoes similar translation procedure but in the opposite direction.

Use of let and into keyword, and how they help in making Progressive queries but still keep Defered execution.


into and let create temporary reference to store the result of a subquery/subexpression that can be later queried itself. These operators keep deferred execution and allow creation of sub routines that can be used incrementally or progressively. Personally, I would rather try simplifying the query, so I will not use either of these keywords. A few separate queries are much debugger [developer] friendly and less bug prone.
As a sample, let can be used to store the count of elements in a group
var categories = from p in products
	group p by p.Category into g
	let elCount = g.Count()
	select new 
	{ 	Category = g.Key, 
		ElementCount = elCount 
	};

Use of IQueryable and IEnumerable interfaces

IEnumerable<T> is applicable for in-memory data querying, in contrast IQueryable<T> allows remote execution, like web service or database querying. 



First of all, IQueryable<T> extends the IEnumerable<T> interface, so anything you can do with a "plain" IEnumerable<T>, you can also do with an IQueryable<T>.
Misuse of the interface can result in performance and memory problems, e.g. if IEnumerable<T> is used instead of IQueryable<T> to perform paging all the rows from data source will be loaded, instead of only those rows from the current page
IEnumerable<T> just has a GetEnumerator() method that returns an Enumerator<T> for which you can call its MoveNext() method to iterate through a sequence of T.
What IQueryable<T> has that IEnumerable<T> doesn't are two properties in particular—one that points to a query provider (e.g., a LINQ to SQL provider) and another one pointing to a query expressionrepresenting the IQueryable<T> object as a runtime-traversable expression that can be understood by the given query provider (for the most part, you can't give a LINQ to SQL expression to a LINQ to Entities provider without an exception being thrown).
The expression can simply be a constant expression of the object itself or a more complex tree of a composed set of query operators and operands. The query provider's IQueryProvider.Execute() orIQueryProvider.CreateQuery() methods are called with an Expression passed to it, and then either a query result or another IQueryable is returned, respectively.

What are Interpreted Queries?


LINQ combines two architectural models: in-memory local and remote.
The first one is basically LINQ-to-Objects and LINQ-to-XML. Local model closely work withIEnumerable<T> and decorator sequences of C# methods, lambdas and delegates. The query is compiled into standard imperative IL code.
The second one is LINQ-to-SQL and LINQ-to-Entities. Remote model in contrast is rather declarative to the runtime. Sequences in query implement the IQueryable<T> (which in turn derives fromIEnumerable<T>) and after the compilation resolve into query operators from Queryable class – expression trees. Depending on the query provider, expression trees will be later interpreted by the runtime and are “friendly” to the remote data source.



So far, we’ve examined the architecture of local queries,which operate over collections implementing IEnumerable<>. Local queries resolve to query operators in the Enumerable class, which in turn resolve to chains of deco-rator sequences. The delegates that they accept—whether expressed in comprehension syntax, lambdasyntax, or tradi-tional delegates—are fully local to Intermediate Language(IL) code just as any other C# method.
Bycontrast, interpreted queries are descriptive. They operate over sequences that implement IQueryable<>, and they resolve to the query operators in the Queryable class, which emit expression trees that are interpreted at runtime.



There are two IQueryable implementations in the .NET Framework:
•LINQ to SQL
•LINQ to Entities
In addition, the AsQueryable extension method generates an IQueryable wrapper around an ordinary enumerable collection.



What are Interpreted Queries?


LINQ combines two architectural models: in-memory local and remote.
The first one is basically LINQ-to-Objects and LINQ-to-XML. Local model closely work withIEnumerable<T> and decorator sequences of C# methods, lambdas and delegates. The query is compiled into standard imperative IL code.
The second one is LINQ-to-SQL and LINQ-to-Entities. Remote model in contrast is rather declarative to the runtime. Sequences in query implement the IQueryable<T> (which in turn derives fromIEnumerable<T>) and after the compilation resolve into query operators from Queryable class – expression trees. Depending on the query provider, expression trees will be later interpreted by the runtime and are “friendly” to the remote data source

Explain Query Expression syntax, Fluent syntax, Mixed Queries.


Query expression syntax is based on the new keywords such as from, select, join, group by, order byetc.
string[] words = { "roll", "removal", "fuse", "accusation", 
                             "capture", "poisoning", "accusation" };

var query = from w in words
            where w.Length > 4
            orderby w ascending
            select w;
This query selects words with more than 4 letters and presents result in the ascending order. Fluent syntax is based on the regular C# methods that are linked in a chain, like this sample from msdn.
List<Customer> customers = GetCustomerList();
 
var customerOrders = customers
	.SelectMany(
		(cust, custIndex) => cust
			.Orders
			.Select(o => 
				"Customer #" + (custIndex + 1) +
				" has an order with OrderID " + o.OrderID));
Mixed syntax means query expression syntax is mixed with fluent method calls, for example it can be used to get the distinct values, first result or to get items as array (which by the way will trigger immediate query execution)