Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • LINQ

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 260
    Comment on it

    LINQ is used for Data querying in a type safe way. Data to be queried can be XML, SQL, and Object etc. Lets have a look at simple LINQ query:

    var items = from employee in db.Employee
                         where Employee.Salary < 20000
                         select new { Employee.Name, Employee.Address };
    

    This will return all the employee names and address who will have salary less than 20000. Sysntax of query looks similar to SQL.

    There are severalfeatures of LINQ we can discuss in this article and they are as follows.

    1. Lambda Expressions Extension Methods
    2. Anonymous Types
    3. Implicitly Typed Local Variables
    4. Object Initializers
    5. Query Expressions

    Lambda Expressions Lambda expressions are similar to anonymous method. Lambda expression treats code as data.

    Lets take the example above and replace the anonymous method with a lambda expression:

    IEnumerable<Employee > locals = 
        EnumerableExtensions.Where(employee, e => e.ZipCode == 248001);
    

    Here we have not used delegate keyword to initialize the construct instead, there is a new operator, =>, which tells the compiler that this isnt a normal expression. The Employee type is inferred from the usage. In this case, the signature of the Where method looks something like:

    public static IEnumerable<T> Where<T>(
        IEnumerable<T> items, Func<T, bool> predicate)
    

    The compiler is able to understand that "e" refers to a employee because the first parameter of the Where method is IEnumerable, such that T must, in fact, be Employee. Using this knowledge, the compiler also verifies that Employee has a ZipCode member. Finally, there is no return keyword specified. In the syntactic form, the return member is omitted but this is merely syntactic convenience. The result of the expression is still considered to be the return value.

    Extension Methods Extension methods help simplify our query, but there are also very useful features of extension methods. The most common will be to provide shared interface implementation. For example, suppose you have the following interface:

    interface IMan
    {
        // Walk for 2 seconds
        void Walk ();
        void Walk (int seconds);
    }
    

    This interface requires that every implementer write an implementation for both overloads.

    interface IMan
    {
        void Walk(int seconds);
    }
    An extension method could be added in another class:
    static class Man Extensions
    {
        // Barks for 2 seconds
        public static void Bark(this IMan man)
        {
            man.Walk(2);
        }
    }
    

    Now we need to implement only one method of Interface and we can use both the methods independently

    Anonymous Types Now if we have to return name and address of employee in from this method then we will run into trouble as we can return only one value from method. For that purpose we need a type that contains both name and address field of employee. i.e.

    class EmployeeTuple
    {
        public string Name;
        public string Address;
    
        public EmployeeTuple(string name, string address)
        {
            this.Name = name;
            this.Address = address;
        }
    }
    

    We could then use that type, here EmployeeTuple, to construct the result of our query:

    IEnumerable<EmployeeTuple> locals = 
        employees.Where(e => e.ZipCode == 248001)
                     .Select(e => new EmployeeTuple(e.Name, e.Address));
    

    But we may need Name and Age of employee and in that case also, the type name should be EmployeeTouple as it contains info about Employee. So, the problem is that it doesnt seem that there are any good names for the types that we create. Plus, there could also be many different types required, and managing them is itself a big problem. This is exactly where we use anonymous type. This feature basically allows the creation of structural types without specifying the name. If we rewrite the query above using anonymous types, heres what it looks like:

    locals = employees.Where(e => e.ZipCode == 248001)
                           .Select(e => new { e.Name, e.Address });
    

    This code implicitly creates a type that has the fields Name and Address:

    class 
    {
        public string Name;
        public string Address;
    }
    

    These types do not have any name. The names of the fields can be declared in the anonymous type creation. For example, if the field being created is derived from a complicated expression, or the name simply isnt desirable, its possible to change the name:

    locals = employees.Where(c => e.ZipCode == 248001)
        .Select(c => new { FullName = e.FirstName +   + e.LastName, 
                           HomeAddress = e.Address });
    

    In this case, the type that is generated has fields named FullName and HomeAddress.

    Implicitly Typed Local Variables Theres another language feature known as implicitly typed local variables (or var for short) that tells the compiler to get the type of a local variable. For example:

    var count= 1;
    

    In this case, count has the type int. Once a type is assigned to a var then it cannot be changed later. i.e.:

    var count= 1;
    count= 1.1;
    

    Here, compiler will throw an error that value of type integer cannot be change to float. That means, we cannot change the variable type once it is assigned a value. In the case of the query above, We can write out query like this:

    var locals =
       employees
           .Where(c => e.ZipCode == 248001)
           .Select(c => new { FullName = e.FirstName +   + e.LastName, 
                              HomeAddress = e.Address });
    

    The type of locals ends up being IEnumerable where "?" is the name of a type that cant be written (since it is anonymous). Implicitly typed locals have their scope within a function or property. They cannot be created globally.

    Object Initializers For this case, there is a C# language feature in the upcoming "Orcas" version known as object initializers. Object initializers basically allow the assignment of multiple properties or fields in a single expression. For example, a common pattern for object creation is:

    Employee employee = new Employee ();
    employee.Name = Abhishek;
    employee.Address = 1 Dehradun;
    

    In this case, there is no constructor of Customer that takes a name and address; however, there are two properties, Name and Address, that can be set once an instance is created. Object initializers allow the same creation with the following syntax:

    Employee employee = new Employee () 
        { Name = Abhishek, Address = 1 Dehradun };
    

    In our earlier EmployeeTuple example, we created the EmployeeTuple class by calling its constructor. We can achieve the same result via object initializers:

    var locals = 
        employees
            .Where(e => e.ZipCode == 248001)
            .Select(e => 
                 new EmployeeTuple { Name = e.Name, Address = e.Address });
    

    Notice that object initializers allow the parentheses of the constructor to be omitted. In addition, both fields and settable properties can be assigned within the body of the object initializer. We now have a succinct syntax for creating queries in C#. However, we also have an extensible way to add new operators (Distinct, OrderBy, Sum, and so on) through extension methods and a distinct set of language features useful in their own right. The language design team now had several prototypes to get feedback on. So we organized a usability study with many participants who had experience with both C# and SQL. The feedback was almost universally positive, but it was clear there was something missing. In particular, it was difficult for the developers to apply their knowledge of SQL because the syntax we thought was ideal didnt map very well to their domain expertise.

    Query Expressions The language design team then designed a syntax that is closer to SQL, known as query expressions. For example, a query expression for our example might look like this:

    var locals = from e in employees
                 where e.ZipCode == 248001
                 select new { FullName = e.FirstName +   +
                              e.LastName, HomeAddress = e.Address };
    

    Query expressions are built on the language features described above. They are literally syntactically translated into the underlying syntax that weve already seen. For example, the query above is translated directly into:

    var locals =
       employees
           .Where(c => e.ZipCode == 248001)
           .Select(c => new { FullName = e.FirstName +   + e.LastName, 
                              HomeAddress = e.Address });
    

    Query expressions support a number of different "clauses," such as from, where, select, orderby, group by, let, and join. These clauses translate into the equivalent operator calls, which in turn, are implemented via extension methods. The tight relationship of the query clauses and the extension methods that implement the operators makes it easy to combine them if the query syntax doesnt support a clause for a needed operator. For example:

    var locals = (from e in employees
                  where e.ZipCode == 248001
                  select new { FullName = e.FirstName +   +
                              e.LastName, HomeAddress = e.Address})
                 .Count();
    

    In this case the query now returns the number of employees who live in the 248001 ZIP Code area. And with that, weve managed to end just about where we started .

 0 Comment(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: