Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#4.0

LINQ Tutorial for Beginners

4.51/5 (35 votes)
10 May 2013CPOL4 min read 383.3K  
A LINQ tutorial for beginners.

LINQ

LINQ is Microsoft’s technology to provide a language-level support mechanism for querying data of all types. These types include in memory arrays and collections, databases, XML documents and more, since version 3.5 and Visual Studio 2008. (.NET 4 and Visual Studio 2010 added support for the Parallel LINQ features).

Need for LINQ

  • Here is the issue that we cannot programmatically interact with a database at the native language level. This means syntax errors often go undetected until runtime.
  • Differing data types utilized by a particular data domain, such as database or XML data types versus the native language
  • XML parsing, iterating, and manipulation can be quite tedious. an XmlDocument must be created just to perform various operations on the XML fragment

Advantages of LINQ

  • Query is integrated into the language. Gone are the days of writing a SQL query into a string and not detecting a syntax error until runtime, for example we forget the name of a field of the table (or reference) or it has been changed in DB.
  • In addition to query features, LINQ to XML provides a more powerful and easier-to-use interface for working with XML data, as though it were a database.
  • Example:

    C#
    XElement books = XElement.Parse(
           @"<books>
                <book>
                <title>Pro LINQ: Language Integrated Query in C#2010</title>
                <author>Joe Rattz</author>
                </book>
                <book>
                <title>Pro .NET 4.0 Parallel Programming in C#</title>
                <author>Adam Freeman</author>
                </book>
                <book>
                <title>Pro VB 2010 and the .NET 4.0 Platform</title>
                <author>Andrew Troelsen</author>
                </book>
                </books>");
    
    //XElement Xbooks = XElement.Parse(@"XMLFile.xml");
    var titles =
    from book in books.Elements("book")
    where (string)book.Element("author") == "Joe Rattz"
    select book.Element("title");
    foreach (var title in titles)
        Console.WriteLine(title.Value);
  • Not only for querying data but for formatting, validating, and even getting data into the necessary format : example string array to integer array and sort. can also use select new for complex classes

    Example:

    C#
    string[] numbers = { "0042", "010", "9", "27" };            
    int[] nums = numbers.Select( 
    s => Int32.Parse(s)).OrderBy(s => ).ToArray(); 
    foreach (int num in nums) 
    Console.WriteLine(num);

Syntax of LINQ

Two syntaxes are available for LINQ queries:

  • Query expression syntax
  • C#
    from str in strings where str.Length==3 select str; 
  • Standard dot notation syntax
  • C#
    stringList.Where(s => s.Length == 3).Select(s=>s); 

Type of LINQ

  • LINQ to Objects
  • LINQ to XML
  • LINQ to DataSet
  • LINQ to SQL
  • LINQ to Entities.

More about LINQ

  • They are queries returning a set of matching objects, a single object, or a subset of fields from an object or set of objects. In LINQ, this returned set of objects is called a sequence, and most LINQ sequences are of type IEnumerable<T>.
  • We can use the "Cast" or "OfType" operators for Legacy Collections to convert them to IEnumerable to use LINQ.
  • The LINQ query actually take place the first time a result from it is needed. This is typically when the query results variable is enumerated.
  • And this may lead to the situation: deferred query is passed undetected with error.--> deferred query example (disadvantage)
  • Example:

    C#
    string[] strings = { "one", "two", null, "three" };
    Console.WriteLine("Before Where() is called.");
    IEnumerable<string> ieStrings = strings.Where(s => s.Length == 3);
    Console.WriteLine("After Where() is called.");            
    foreach (string s in ieStrings) 
    { 
      Console.WriteLine("Processing " + s); 
    }
  • Calling the actual query each time is needless work. It might make more sense to have a query initialization method that gets called once for the lifetime of the scope and to construct all the queries there (advantage).
  • C#
    List<string> strings = new List<string>(); 
    strings.Add("one"); 
    strings.Add("two"); 
    strings.Add("three"); 
    
    IEnumerable<string> ieStrings = strings.Where(s => s.Length == 3); 
    foreach (string s in ieStrings) 
    { 
      Console.WriteLine("Processing " + s); 
    } 
    
    Console.ReadKey(); 
    strings.Add("six"); 
    Console.WriteLine("source enumerable changed but query is not invoked again"); 
    //query is not invoked explicitly, ieStrings is not changes 
    foreach (string s in ieStrings) 
    { 
      Console.WriteLine("Processing " + s); 
    }
  • In Linq To Entity, string can be passed in where clause as a condition using “it” as variable refenrence.
  • Example:

    C#
    VCAB_CMS_DBEntities context = new VCAB_CMS_DBEntities(); 
    string condition = "it.DocName=='Shakuntala Devi'"; 
    int pageCount= context.EDOC.Where(condition).Select(c => c.DocPageCount).First(); 

Language additions with LINQ

Lambda expressions

C#
i => ((i & 1) == 1)

This expression refers to an anonymous method with left side as input to the method and right side as the output.

Expression trees

C#
IEnumerable<int> numsLessThanFour = nums.Where(i => i < 4).OrderBy(i => i);

The Where operator is called first, followed by the OrderBy operator. But an expression tree allows the simultaneous evaluation and execution of all operators in a query, a single query can be made instead of a separate query for each operator.

The keyword var, object and collection initialization, and anonymous types

C#
var address = new { address = "105 Elm Street", 
  city = "Atlanta", state = "GA", postalCode = "30339" };

Compiler generated anonymous class name looks like: <>f__AnonymousType5`4[System.String,System.String,System.String,System.String].

Collection initialization allows you to specify the initialization values for a collection, just like you would for an object:

C#
List<string> presidents = new List<string> { "Adams", "Arthur", "Buchanan" };

Extension methods

  • Used to extend a sealed class like adding factorial method in int class or adding todouble method in string class.
  • Extension methods are methods that, although static, can be called on an instance (object) of a class rather than on the class itself.
  • Specifying a method’s first argument with the “this” keyword modifier will make that method an extension method.
  • Extension methods can be declared only in static classes.
C#
public static class ExtendsStringClass{ 
    public static double ToDouble(this string s){ 
        return Double.Parse(s); 
    } 
} 

class Program{ 
static void Main(string[] args){ 
        double pi = "3.1415926535".ToDouble(); 
        Console.WriteLine(pi); 
        MyWidget myWidget = new MyWidget(); 
        Console.ReadKey(); 
    }     
} 

Partial methods

  • A partial method can exist only in a partial class
  • A partial method must return void.
  • Partial methods are private but must not specify the private modifier

Example: To make the generated entity classes more usable, partial methods have been added to them. You can add another module that declares the same entity class, implement these partial methods, and be notified every time a property is about to be changed and after it is changed

Query expressions

  • Query expressions allow LINQ queries to be expressed in nearly SQL form, with just a few minor deviations.
  • The “from” statement precedes the select statement, hence intelliSense has the scope of what variables to offer you for selection.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)