Attention: open in a new window. PDFPrint

Some LINQ Experience

As my girlfriend asked me to write her a little application that should use auto completion on a textbox, I started playing around with LINQ yesterday and decided to post a little article that might help you to understand what LinQ is and show some exaples, how you might use it. As a start, lets quote what Microsoft says about LINQ:

"LINQ is a set of extensions to the .NET Framework that encompass language-integrated query, set, and transform operations. It extends C# and Visual Basic with native language syntax for queries and provides class libraries to take advantage of these capabilities."

The Idea behind LINQ is nothing really new as there are several technologies out there doing equal things like hibernate and so on. New is, that the LINQ-syntax is directly integrated into the syntax of the source language. This is something no other language provides like this. LINQ allows you to write queries on datastructures and datasources directly into your sourcecode and keeps your sourcecode clear. It also allows easy encapsulation of datasource types as you use a high level interface to access SQL databases (for example).



A nice feature that I used is that you can perform LINQ-queries on any iterable data structure provided by the .NET framework like List<T>, LinkedList<T>, HashMap<T> and so on. Just to make clear, what this means, let's look at the following example.

At first, we design a simple sample data type containing some information that we can use for our queries:


 

    class Car

    {

        /// <summary>

        /// Color of our car.

        /// </summary>

        private String color;

 

        /// <summary>

        /// Maximum speed of our car.

        /// </summary>

        private float maxSpeed;

 

        /// <summary>

        /// The manufacturer of our car.

        /// </summary>

        private String manufacturer;

 

        /// <summary>

        /// Our cars constructor presetting all values.

        /// </summary>

        /// <param name="color">The color of the car.</param>

        /// <param name="maxSpeed">The maximum speed.</param>

        /// <param name="manufacturer">The cars manufacturer</param>

        public Car(String color, float maxSpeed, String manufacturer)

        {

            this.color = color;

            this.manufacturer = manufacturer;

            this.maxSpeed = maxSpeed;

        }

 

        /// <summary>

        /// Getter for the color of the car.

        /// </summary>

        public String Color

        {

            get { return this.color; }

        }

 

        /// <summary>

        /// Getter for the manufacturer.

        /// </summary>

        public String Manufacturer

        {

            get { return this.manufacturer; }

        }

 

        /// <summary>

        /// Getter for the maximum speed.

        /// </summary>

        public float MaxSpeed

        {

            get { return this.maxSpeed; }

        }

    }

 

 

As you can see, the class above is nothing than a model representation of a car. It contains the values to read and some properties to provide them to the application. So let's define a LinkedList with some cars within:

            LinkedList<Car> carList = new LinkedList<Car>();

            carList.AddLast(new Car("Blue", 240.0f, "RoadRacer"));

            carList.AddLast(new Car("Green", 120.0f, "SpaceCar3000"));

            carList.AddLast(new Car("Red", 140.0f, "SpaceCar3000"));

            carList.AddLast(new Car("Black", 160.0f, "FairDrive"));

            carList.AddLast(new Car("Yellow", 200.0f, "SpaceCar3000"));

And that is all setup we need. Now we can get ahead and perform some queries on our data structure. The next one is very easy. You might think that a simple foreach-loop would do, but there will be some more interesting queries later on. The advantage of the LINQ version of the algorithm over the selfmade foreach-loop is, that the LINQ version is easier to understand and to change, if your requirements change. Lets go ahead:

            var colorsOfSC3000 =

                        from Car car in carList

                        where car.Manufacturer.Equals("SpaceCar3000")

                        select car.Color;

 

            Console.Write("Colors of Cars manufactured by SpaceCar3000: ");

            foreach (String color in colorsOfSC3000)

            {

                Console.Write(color + " ");

            }

            Console.WriteLine();

The query just lists all colors of cars produced by SpaceCar3000. As you can see above that colors are green, red and yellow. The LINQ syntax looks a little bit like SQL statements in an odd order. As you might expect you can use statements like orderby as well. The first line of the statement defines the objects we request: We do this for every Car object in the carList. The instance of the current car object is stored into the local variable car. The next line defines which cars we want to request. In this case, we ignore all cars not manufactured by SpaceCar3000. The last line defines which object we want to return. We read the cars color only in this case, as we are not interested in other values. Afterwards we can iterate over the result of our query by using a foreach-loop. Of course you could easily replace the LINQ snipped above against the following loop:

            Console.Write("Colors of Cars manufactured by SpaceCar3000: ");

            foreach (Car car in carList) {

                if (car.Manufacturer.Equals("SpaceCar3000")

                    Console.Write(car.Color);

            }

            Console.WriteLine();

It gets more interesting if you perform some stuff like ordering the result of the LINQ statement:

            var highSpeed =

                from Car car in carList

                where car.MaxSpeed > 180.0f

                orderby car.MaxSpeed

                select car;

 

            Console.WriteLine("\nHigh-Speed cars:");

            foreach (Car car in highSpeed)

            {

                Console.WriteLine("The " + car.Color + " car from " + car.Manufacturer

                    + " has a maximum speed of " + car.MaxSpeed + ".");

            }

The orderby statement forces LINQ to order the Cars by their maximum speed value. In this case, LINQ makes your query very easy. To perform the same stuff using a foreach-loop you would need to order your car-list before sorting the unneded objects out or write them to a new list and sort the list after sorting the objects out or write them to an ordered list. All options are more complex than using the LINQ statement instead.

An other feature that is very nice is the option to receive distinct results by using the Distinct<>()-Method on your query:

            var manufacturers =

                (from Car car in carList

                 orderby car.Manufacturer

                 select car.Manufacturer).Distinct<String>();

            Console.WriteLine("\nKnown manufacturers:");

            foreach (String manufacturer in manufacturers) {

                Console.WriteLine(manufacturer);

            }


The Method returns all manufacturers of cars in the car list in a sorted order. I think you will agree that using LINQ in this case would you also save some work in this case.