Click here to Skip to main content
Email Password   helpLost your password?
Figure 1

Figure 2

Contents

Introduction

This article is about LINQ which I think is one of the most exciting features in Orcas. LINQ makes the concept of querying a first-class programming concept in .NET. The data to be queried can take the form of XML (LINQ to XML), databases (LINQ-enabled ADO.NET: LINQ to SQL, LINQ to Dataset and LINQ to Entities) and objects (LINQ to Objects). LINQ is also highly extensible and allows you to build custom LINQ enabled data providers (e.g.: LINQ to Amazon, LINQ to NHibernate, LINQ to LDAP).

LINQ Architecture (MSDN Magazine - June 2007)

I will discuss some of the new language features and improvements that are introduced in C# 3.0, and it is those features that enable the full power of LINQ which makes it possible to write something like this:

var result = from c in Customers
             where c.City == Boston"
             orderby c.LastName descending
             select new { c.FirstName, c.LastName, c.Address };

Remember that if you want to play around with LINQ or try the examples yourself, you will need to download Visual Studio Orcas Beta 1.
In case you don't want to download Visual Studio, you can check the LINQ Preview (May 2006 CTP) which runs on top of Visual Studio 2005 (there are a few changes in Beta 1 from the way LINQ worked in the May CTP).

New Language Features

I. Automatic Properties

public class Point {
    private int _x, _y;
    public int X {
        get { return _x; }
        set { _x = value; }
    }
    public int Y {
        get { return _y; }
        set { _y = value; }
    }
}

The above code simply defining a class with basic properties. Now with the new C# compiler in Orcas, we can write a shorter cleaner version using Automatic Properties which automatically generates the private fields with get/set operations :

public class Point {
    public int X { get; set; }
    public int Y { get; set; }
}

The code above is even more readable and less verbose.
Note that this feature has nothing to do with LINQ. I just thought it would be appropriate to list it with the other new language features.

II. Local Variable Type Inference

With this feature, the type of the local variable being declared is inferred from the expression used to initialize the variable. This is achieved using the var keyword (familiar to those who work with scripting languages, but actually it is quite different). It allows us to write the following code:

var num = 50;
var str = "simple string";
var obj = new myType();
var numbers = new int[] {1,2,3};
var dic = new Dictionary<int,myType>();

The compiler would generate the same IL as if we compiled:

int num = 50;
string str = "simple string";
myType obj = new myType();
int[] numbers = new int[] {1,2,3};
Dictionary<int,myType> dic = new Dictionary<int,myType>();

Note that there is no un-typed variable reference nor late-binding happening, instead the compiler is inferring and declaring the type of the variable from the right-hand side of the assignment. As a result, the var keyword is generating a strongly typed variable reference.

III. Object Initializers & Collection Initializers

Let's use the same Point class defined earlier, and suppose we want to define an instance of this class. We will have to create the object and start setting its properties, the code would look like this:

Point p = new Point();
p.X = 0;
p.Y = 0;

This could be rewritten using Objects Initializers and combined into:

Point p = new Point() { X = 0, Y = 0 };

This feature can also be used with collection. Take a look at this example:

List<Point> points = new List<Point> {
    new Point { X = 2,  Y = 5 },
    new Point { X = 1, Y = -10 },
    new Point { X = 3, Y = 0 }
};

Note that the compiler will generate a long hand code equivalent to the above one. It makes calls to the Add() method to add elements to the collection one at a time.

IV. Anonymous Types

This language feature enable us to define inline types without having to explicitly define a class declaration for this type. In other words, imagine we want to use a Point object without defining the class Point (it would be anonymous). We will use the same object initializer syntax discussed earlier, but without the type name:

var p = new {X = 0, Y = 2};

Inside Orcas, you will have full intellisense support. So when you use the variable p you will get a list of properties that this anonymous type has.

V. Lambda Expressions

C# 2.0 introduced anonymous methods, which allow code blocks to be written "in-line" where delegate values are expected. While anonymous methods provide the power of functional programming languages, the syntax is rather verbose. Lambda expressions provide a more concise, functional syntax for writing anonymous methods. A lambda expression is written as a parameter list (can be implicitly typed), followed by the => token, followed by an expression or a statement block.

As an example, let's define a delegate type MyDeleg as:

delegate R MyDeleg<A,R>(A arg);

We can then write using anonymous methods:

MyDeleg<int,bool> IsPositive = delegate(int num) {
                                   return num > 0;
                               };

Or we can use the new lambda expressions to write:

MyDeleg<int,bool> IsPositive = num => num > 0;

VI. Extension Methods

Extension methods make it possible to extend existing types and constructed types with additional methods, without having to derive from them or recompile the original type. So instead of writing helper methods for objects, they become part of that object itself.

As an example, suppose we want to check a string to see if it is a valid email address. We would do this by writing a function that takes a string as an argument and returns a true/false. With Extension Methods, we can do the following:

public static class MyExtensions {
    public static bool IsValidEmailAddress(this string s) {
        Regex regex = new Regex( @"^[w-.]+@([w-]+.)+[w-]{2,4}$" );
        return regex.IsMatch(s);
    }
}

We defined a static class with a static method containing the Extension Method. Note how the static method above has a this keyword before the first parameter argument of type string. This tells the compiler that this particular Extension Method should be added to objects of type string. And then we can call it from the string as a member function:

using MyExtensions;

string email = Request.QueryString["email"];
if ( email.IsValidEmailAddress() ) {
    // ...
}

It is worth mentioning that LINQ syntax makes use of built-in Extension Methods (e.g. where(), orderby(), select(), sum(), average() and many more) that reside in the new System.Linq namespace in Orcas and define standard query operators that can be used against relational databases, XML and any .NET objects that implement IEnumerable<T>.

VII. Query Syntax

Query expressions provide a language integrated syntax for queries that is similar to relational and hierarchical query languages such as SQL and XQuery. It is a shorthand for writing queries using the LINQ query operators (i.e. from...where...select). Visual Studio provides full intellisense and compile-time checking support for query syntax.
When the C# compiler encounters a query syntax expression, it actually transforms it into explicit method invocation code that uses Extension Methods and Lambda Expressions.

To explain this, let me give an example:

var result = from c in Customers
             where c.City.StartsWith("B")
             orderby c.LastName
             select new { c.FirstName, c.LastName, c.Address };

The above code is equivalent to the following:

var result = Customers.Where( c => c.City.StartsWith("B") )
                      .OrderBy( c => c.LastName  )
                      .Select( c => new { c.FirstName, c.LastName, c.Address } );

The advantage of using Query Syntax is that the code is easier and more readable.
Also note that a query expression begins with a from clause and ends with either a select or group clause.

Final Notes

Most of the language features introduced in C# v3.0 that we saw (such as variable type inference, object initializers, anonymous types and lambda expressions) are only "compiler tricks"/"syntactic sugar" which means that the IL the compiler generates is the same as the long code version, therefore they are independent from the framework (NetFX) and runtime (CLR). However, they do need some framework support and specifically the "green bits" (.NET Framework v3.5) System.Core.dll assembly. This is why extension methods, which in fact work at compile time (syntactic sugar), still rely on System.Runtime.CompilerServices.ExtensionAttribute introduced in System.Core.dll.
On the other hand, query expressions syntax is just a mapping to the extension methods implementations that resides in System.Linq, System.Data.Linq and System.Xml.Linq namespaces.

References & Resources

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralLINQ sandbox
petersummers
5:54 8 Oct '09  
Hey,

While trying to get to know some LINQ, I've found a nice sandbox that helped a lot.
It's some kind of online IDE that also supports LINQ and has some samples from 101linq that you can play around with and see what happens, without downloading anything.

http://coderun.com/Code/?q=from%3aLinqLuther[^]

Cheers,
PS
QuestionTransform details collection into a grouped list with details
ioranet
14:41 21 May '09  
I'm quite new to LINQ and hope that someone could help me find an elegant way of making this type of query.
I have a table of invoices and I want to select out all the invoices created on a certain date, then based on this, I want to generate a report on the list showing the invoices, grouped by the customer and the list of invoices for that customer.
something like :-
var result = from c in invoices
                  where date=<selected date>
                  select new {c.customer, <c.invoice_num_list>};

where the <c.invoice_num_list> is a collection of invoice numbers for c.customer for the selected date.
I can write several queries to achieve the result but was wondering if there is a better way to do this.
Thanks
GeneralSeraching by LINQ ?
Mohammad Dayyan
16:24 7 Aug '08  
Hi there Amro .
It's very nice article.
I have a question .

I have a XML file like this :
<NODE15>
<BOOKMARK16 NAME="Mozilla - Home" HREF="http://en-us.www.mozilla.com/en-US/" />
<BOOKMARK18 NAME="mozillaZine Forums" HREF="http://forums.mozillazine.org/index.php" />
<BOOKMARK19 NAME="Mozilla Support" />
<BOOKMARK20 HREF="http://www.download.com/" />
<BOOKMARK21 HREF="http://firefoxplanet.ir/" />
<BOOKMARK22 HREF="http://developer.mozilla.org/en/docs/Extensions" />
<BOOKMARK23 HREF="http://forums.mozillazine.org/viewforum.php?f19" />
<BOOKMARK24 HREF="https://addons.mozilla.org/en-US/firefox/addon/5229" />
</NODE15>
I want to search in it by LINQ.
I used this code
X_Element = XElement.Load(FileName);
var searchNodes = from nodes in X_Element.Descendants()
where Regex.IsMatch(nodes.Attribute("HREF").Value, "Mozilla", RegexOptions.IgnoreCase)
select nodes;
But there is no data in searchNodes What's wrong with it ?
Please help me .
Thanks in advance
GeneralGood work
mithun.nss
0:02 7 Aug '08  
Nice to know about this new language features, coming in to .NET FX.
Hope the same will also be available in VC++.NET (MC++).Suspicious Cool

-
Sundar Smile

mithun.nss

GeneralNice topic on C# 3.0
Chintan.Desai
2:32 21 Jul '08  
... Smile

Regards
Chintan
HCL Technologies...India
(Carefully) listen->(Deeply)Think->(Clearly)Understand->(Patiently) reply...

GeneralGood efforts...Good for beginners..
The Ruler
2:25 17 Jul '08  
Hi,

Very good article for beginners. Thanks for your efforts.

Thanks & Regards,

Viresh Shah

GeneralCould you help me to translate this into LINQ?
semenoff
4:36 18 Jan '08  
Hi.

Thanks for very interesting article. I am a bit new to LINQ programming and I have some troubles trying to translate one of my SQL queries into LINQ.

I need to select a list of newest orders for customers. In Nortwind database it would look like this:

SELECT     OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate, ShippedDate, ShipVia, Freight, ShipName, ShipAddress, ShipCity, ShipRegion, 
ShipPostalCode, ShipCountry
FROM Orders
WHERE (OrderDate =
(SELECT MAX(OrderDate) AS Expr1
FROM Orders AS Orders_1
WHERE (CustomerID = Orders.CustomerID)))
ORDER BY CustomerID, OrderDate

Could you help me to rewrite it in LINQ?

Thanks in advance for help.

// semenoff
Generalcould use more info in LINQ
CIDev
7:38 28 Nov '07  
You have given concise explanations of the new features in VS 2008 (was codenamed Orcas); this can be very helpful for someone who is trying to learn about what’s new in VS 2008. My only complaint is that the title of your article is “Understanding LINQ” and you don’t go into a lot of depth on that subject.
GeneralRe: could use more info in LINQ
Amro Khasawneh
9:16 28 Nov '07  
CIDev wrote:
My only complaint is that the title of your article is “Understanding LINQ” and you don’t go into a lot of depth on that subject

You're probably right as I didn't go into details about LINQ but I tried to explain the new language features in C# 3.0 that makes it possible, hence get a better understating of LINQ (i believe the subtitle is more clarifying). Keep in mind that I marked this article as "Beginner"..
Also there are a number of other articles here on CP that you could use.


CIDev wrote:
VS 2008 (was codenamed Orcas)

At the time i wrote the article it was VS Orcas Beta 1, however the basics remain the same.


Amro Khasawneh
GeneralRe: could use more info in LINQ
CIDev
9:43 28 Nov '07  
Amro Khasawneh wrote:
CIDev wrote:
My only complaint is that the title of your article is “Understanding LINQ” and you don’t go into a lot of depth on that subject


You're probably right as I didn't go into details about LINQ but I tried to explain the new language features in C# 3.0 that makes it possible, hence get a better understating of LINQ (i believe the subtitle is more clarifying). Keep in mind that I marked this article as "Beginner"..
Also there are a number of other articles here on CP that you could use.

I definately think it is a useful article, this was just a small quibble on my part.



Amro Khasawneh wrote:
CIDev wrote:
VS 2008 (was codenamed Orcas)


At the time i wrote the article it was VS Orcas Beta 1, however the basics remain the same.


Yes, I put in both names because someone will inevitably get confused due to the name change.

Bill

Generalcompare with nhibernate
kianoosh soorani
1:55 11 Nov '07  
please compare LINQ With nHibernate

GeneralRe: compare with nhibernate
Amro Khasawneh
15:50 11 Nov '07  
First let me say that i haven't really used NHibernate before, maybe someone else could offer you a better explanation..
One thing though you should realize is that LINQ and the ORMs built on LINQ are two separate things; LINQ is a set of language extensions, while LINQ to SQL for example is an ORM with LINQ as its query language.
LINQ is extensible and allows you to perform queries against any data provider or O/R implementation like NHibernate by taking advantage of the Expression Tree support provided with Lambdas and the IQueryable interface.
I believe there already exist a LINQ to NHibernate custom provider, just google it..

Also I found a few links that may be helpful:
http://tanveerbadar.wordpress.com/2007/10/14/linqentity-framework-vs-nhibernate/ http://msdn2.microsoft.com/en-us/library/Aa479863.aspx
GeneralVery good for beginner
Anjum.Rizwi
7:47 4 Oct '07  
Very good for beginner
GeneralRe: Very good for beginner
Amro Khasawneh
6:28 9 Oct '07  
Thanks, glad I could help

Amro Khasawneh
GeneralCool... Nice explanation
Ayyanar
0:16 5 Jul '07  
Cool... Nice explanation

Ayyanar. J
Senior Software Engineer
Puducherry
India

GeneralVery good concise Linq introduction artcile
aerradi
15:37 19 Jun '07  
Thanks Amro, this is excellent Linq introduction artcile. I enjoyed it. Thanks for your effort.
Regards
Karim
General;)wonderful,amazing,..
Alloch
11:27 18 Jun '07  
WAW Thanks man realy it is helpful ,as it was fun to learn all of this from u.
GooD LucK
Yours,
Computergy.
GeneralRe: ;)wonderful,amazing,..
Amro Khasawneh
0:15 19 Jun '07  
Im glad it helped you.

Amro Khasawneh
GeneralVery Helpful
merlin981
4:19 13 Jun '07  
Thanks, this was very helpful


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I theme/skin my controls and apps with Themer
I get my developer tools from Merlin A.I. Soft
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Generalvery nice
Sacha Barber
1:48 13 Jun '07  
very nice

Sacha Barber A Modern Geek - I cook, I clean, I drink, I Program. Modern or what?

My Blog : sachabarber.net

GeneralRe: very nice
Amro Khasawneh
2:36 13 Jun '07  
Thanks


Last Updated 12 Jun 2007 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010