Part 1: LINQ Tips & Tricks [Things to get you started efficiently]
While my development with LINQ I got around some helps, links, small
tips and tricks which makes life much easier, improves query formulation
capabilities and speedup the program execute performance. Here I am
sharing some of the tips I found as a LINQ Developer.
[1] Use the var Keyword When Confused
Use var keyword as return type especially when you are capturing
sequence of anonymous classes. For example, joining of 2 tables and
retrieving a sequence of records containing (some/few) fields of both
the tables. I appreciate the developers who understand and know exactly
what data type is contained in the sequence they are retrieving. But,
anyhow you get stuck and don’t know the sequence IEnumerable<T>
holds what data type T; then var is the good choice.
[2] Use the Cast or OfType Operators for Legacy Collections
You notice that LINQ standard operators and methods always been
called only on the type of collections/sequence which are implementing
IEnumerable <T> interface. Something trivial to know that none of
the legacy Collection types which are inside System.Collection namespace
implements IEnumerable <T> interface. Then how would you use LINQ
operators and methods against them? The answer is: Cast and OfType LINQ
operators.
//--Cast Example:
//--create a legacy collection of type ArrayList.
ArrayList nameList = new ArrayList();
nameList.Add("Kaushal");
nameList.Add("Pooja");
nameList.Add("Naman");
IEnumerable<string> firstnames = nameList.Cast<string>().Where(n => n.Length > 5);
foreach (string name in firstnames)
Response.Write(name);
//--OfType Example:
//--create a legacy collection of type ArrayList.
ArrayList nameList = new ArrayList();
nameList.Add("Kaushal");
nameList.Add("Pooja");
nameList.Add("Naman");
IEnumerable<string> firstnames = nameList.OfType<string>().Where(n => n.Length > 5);
foreach (string name in names)
Response.Write(name);
Both will result in “Kaushal” here.
[3] Don’t Assume a Query Is Bug-Free
Check out this example:
var names =
from fullname in person
where fullname.EndsWith("Parik")
select fullname;
foreach (var name in names)
Console.WriteLine(name);
By looking at the above example; it appears that query execution is
occurring just when names variable of type var is initialized, but that
is not the case. The reason is LINQ queries are often “deferred” and not
executed when it appears to be executing when you are calling them.
Because “Select” and “Where” statements are deferred operators, above
query will not be executed until you enumerate it. The query is merely
being declared, or defined, but not performed in the very first
statement of above example. Query execution will happen when foreach
statement is executed. So, finally we can say that above query that we
have written is “deferred”! So, keep twice watch on your queries, they
might be culprit for slow performance or internal exception.
[4] Take Advantage of Deferred Query
Now as we are families that Deferred Queries don’t execute until you
enumerate them. Ultimately Deferred Query returns an
IEnumerable<T> can be enumerated over, time and time again,
obtaining the latest data from the data source. You don’t need to
actually call or, as we earlier pointed out, declare the query again.
[5] Use the DataContext Log
This is something similar with using “Sql Server Profiler” tool we
are using when working with our database to debug the query execution.
You can always use “SQL Server Profiler” to view the Sql query generated
by LINQ, but there is a DataContext.Log Property that you can assign to
a TextWriter to view the generated Sql query. Remember that your LINQ
DataContext class inherits from System.Data.Linq.DataContext, which
means LINQ DataContext class is already having some pre-defined in-built
functionality like this Log property.
using (NorthwindDataContext context = new NorthwindDataContext())
{
context.Log = new DebuggerWriter();
Customer customer = context.Customers.Single<Customer>
(c => c.CustomerID.Equals("KPN1"));
}
[6 ] Always Consume DataContext Class object inside using(…) statement
The DataContext dbml class implements IDisposable interface; so, its
always good practice to declare and use the DataContext class inside
using(…) scope sothat object will be disposed immediately after the
defined scope. This is something looks a minor thing but later on in a
heavy database operation related application you may end up with
“Maximum Connection Pooling reached” error if DataContext objects don’t
disposed correctly.
Example:
using (NWindDataContext context = new NWindDataContext())
{
var fullnames = from names in context.Persons
where names.FirstName.ToLower().EndsWith("parik")
select names;
//--further code
}
[7] Use the LINQ Forum
Got stuck somewhere? Don’t forget that is a community forum dedicated
to LINQ at MSDN com (http://www.linqdev.com). This community forum is
monitored by Microsoft developers, and you will find a wealth of
knowledgeable resources and threads there.
[8 ] Use tool like LinqPad
The success behind a LINQ application that you develop lies behind
the performance of the query that you formulate. You can use any third
party tool like I prefer to use LINQPad (by Joseph Albahari) while my development with LINQ.
Actually, quick since a long time after I got to know about this tool
and I was impressed so much that I thought to why not I get aware
something about such nice and intelligent tool before. Life would have
become easier!
hope the tips would help./.
Reference: Apress: Pro LINQ: Language Integrated Query in C# 2010
more to come on EF & LINQ.