Friday, 20 December 2013

LINQ Examples 3

Collection methods id LINQ

Collection methods

Using LINQ, you can modify existing collections, or collections created using other LINQ queries. LINQ provides you a set of functions that can be applied to collections. These functions can be grouped into the following types:
  • Set functions - functions that can be used for collection manipulation operations like merging, intersection, reverse ordering, etc.,
  • Element function - functions that can be used to take particular elements from collections,
  • Conversion functions - functions used to convert a type of collection to another,
  • Aggregation functions - SQL-like functions that enable you to find a maximum, sum, or average value of some field in collections,
  • Quantifier functions - used to quickly traverse through a collection.
These functions are described in the following sections.

Set functions

Set operators enable you to manipulate collections and use standard set operations like unions, intersects, etc. LINQ set operators are:
  • Distinct - used to extract distinct elements from a collection,
  • Union - creates a collection that represents the union of two existing collections,
  • Concat - add elements from one collection to another collection,
  • Intersect - creates a collection that contains elements that exist in both collections,
  • Except - creates a collection that contains elements that exist in one, but do not exist in another collection,
  • Reverse - creates a copy of a collection with elements in reversed order,
  • EquallAll - checks whether two collections have the same elements in the same order,
  • Take - this function takes a number of elements from one collection, and places them in a new collection,
  • Skip - this function skips a number of elements in a collection,
Assuming that the booksByTitle and filteredBooks collection are created in previous examples, the following code finds all books in booksByTitle that do not exist in filteredBooks, and reverses their order.
IEnumerable<Book> otherBooks = booksByTitle.Except(filteredBooks);            

otherBooks = otherBooks.Reverse();  

foreach (Book book in otherBooks)
   Console.WriteLine("Other book - {0} ",  book.Title);
In the following example, booksByTitle and filteredBooks are concatenated and the number of elements and number of distinct elements is shown.
IEnumerable<Book> mergedBooks = booksByTitle.Concat(filteredBooks);
Console.WriteLine("Number of elements in merged collection is {0}", mergedBooks.Count());
Console.WriteLine("Number of distinct elements in merged collection is {0}", mergedBooks.Distinct().Count());

Paging example

In this example is shown an example of client side paging using the Skip(int) and Take(int) methods. Assuming that there are ten books per page, the first three pages are skipped using Skip(30) (ten books per page placed on three pages), and all books that should be shown on the fourth page are taken using Take(10). An example code is:
IEnumerable<Book> page4 = booksByTitle.Skip(30).Take(10);            

foreach (Book book in page4)                
    Console.WriteLine("Fourth page - {0} ", book.Title);
There is also an interesting usage of the Skip/Take functions in the SkipWhile/TakeWhile form:
IEnumerable<Book> page1 = booksByTitle.OrderBy(book=>book.Price)            
                                      .SkipWhile(book=>book.Price<100)
                                      .TakeWhile(book=>book.Price<200);
foreach (Book book in page1)                
    Console.WriteLine("Medium price books - {0} ", book.Title);
In this example, books are ordered by price, all books with price less than 100 are skipped, and all books with price less than 200 are returned. This way all books with price between 100 and 200 are found.

Element functions

There are several useful functions that can be applied when you need to extract a particular element from a collection:
  • First - used to find the first element in a collection. Optionally you can pass a condition to this function in order to find the first element that satisfies the condition.
  • FirstOrDefault - used to find the first element in a collection. If that kind of element cannot be found, the default element for that type (e.g., 0 or null) is returned.
  • ElementAt - used to find the element at a specific position.
The following example shows the usage of the FirstOrDefault and ElementAt functions:
Book firstBook = books.FirstOrDefault(b=>b.Price>200);              
Book thirdBook = books.Where(b=>b.Price>200).ElementAt(2);
Note that you can apply functions either on the collection, or on the result of some other LINQ function.

Conversion functions

There are a few conversion functions that enable you to convert the type of one collection to another. Some of these functions are:
  • ToArray - used to convert elements of collection IEnumerable<T> to array of elements <T>.
  • ToList - used to convert elements of collection IEnumerable<T> to list List<T>.
  • ToDictionary - used to convert elements of a collection to a Dictionary. During conversion, keys and values must be specified.
  • OfType - used to extract the elements of the collection IEnumerable<T1> that implements the interface/class T2, and put them in the collection IEnumerable<T2>.
The following example shows the usage of the ToArray and ToList functions:
Book[] arrBooks = books.ToArray();
List<Book> lstBook = books.ToList();
ToDictionary is an interesting method that enables you to quickly index a list by some field. An example of such a kind of query is shown in the following listing:
Dictionary<string, Book> booksByISBN = books.ToDictionary(book => book.ISBN);
Dictionary<string, double> pricesByISBN = books.ToDictionary(    book => book.ISBN, 
                                book=>book.Price);
If you supply just one lambda expression, ToDictionary will use it as a key of new dictionary while the elements will be the objects. You can also supply lambda expressions for both key and value and create a custom dictionary. In the example above, we create a dictionary of books indexed by the ISBN key, and a dictionary of prices indexed by ISBN.

Quantifier functions

In each collection, you can find a number of logical functions that can be used to quickly travel through a collection and check for some condition. As an example, some of the functions you can use are:
  • Any - checks whether any of the elements in the collection satisfies a certain condition.
  • All - checks whether all elements in the collection satisfies a certain condition.
An example of usage of functions is shown in the following example:
if(list.Any(book=>book.Price<500)) 
    Console.WriteLine("At least one book is cheaper than 500$"); 

if(list.All(book=>book.Price<500))  
    Console.WriteLine("All books are cheaper than 500$");
In the example above, the All and Any functions will check whether the condition that price is less than 500 is satisfied for books in the list.

Aggregation functions

Aggregation functions enable you to perform aggregations on elements of a collection. Aggregation functions that can be used in LINQ are Count, Sum, Min, Max, etc.
The following example shows the simple usage of some aggregate functions applied to an array of integers:
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };

Console.WriteLine("Count of numbers greater than 5 is {0} ", numbers.Count( x=>x>5 ));
Console.WriteLine("Sum of even numbers is {0} ", numbers.Sum( x=>(x%2==0) ));
Console.WriteLine("Minimum odd number is {0} ", numbers.Min( x=>(x%2==1) ));
Console.WriteLine("Maximum is {0} ", numbers.Max());
Console.WriteLine("Average is {0} ", numbers.Average());
As you can see, you can use either standard aggregation functions, or you can preselect a subset using a lambda condition.

LINQ Examples 2

LINQ - Using Quantifiers like Any, Contains and All while Querying Objects
Quantifier operations return a Boolean value if some or all of the elements in a sequence satisfy a condition. In this article, we will see some common LINQ to Objects scenarios where we can use these operators.
There are 3 Quantifiers operations that can be used in LINQ:
All – used to determine whether all the elements in a sequence satisfy a condition.
Any - used to determine whether any elements in a sequence satisfy a condition.
Contains - used to determine whether a sequence contains a specified element
 
List<Department> dept = new List<Department>();
    dept.Add(new Department() { DeptID = 1, DeptName = "Marketing", Floor = 1 });
    dept.Add(new Department() { DeptID = 2, DeptName = "Sales", Floor = 2 });
    dept.Add(new Department() { DeptID = 3, DeptName = "Adminis", Floor = 3 });
    dept.Add(new Department() { DeptID = 4, DeptName = "Accounts", Floor = 3 });
    dept.Add(new Department() { DeptID = 5, DeptName = "HR", Floor = 3 });
 
    List<Employee> emp = new List<Employee>();
    emp.Add(new Employee() { EmpID = 1, DeptID = 1, EmpName = "Jack Nolas"});
    emp.Add(new Employee() { EmpID = 2, DeptID = 4, EmpName = "Mark Pine" });
    emp.Add(new Employee() { EmpID = 3, DeptID = 3, EmpName = "Sandra Simte" });
    emp.Add(new Employee() { EmpID = 4, DeptID = 4, EmpName = "Larry Lo"});
    emp.Add(new Employee() { EmpID = 5, DeptID = 3, EmpName = "Sudhir Panj" });
    emp.Add(new Employee() { EmpID = 6, DeptID = 2, EmpName = "Kathy K" });
    emp.Add(new Employee() { EmpID = 7, DeptID = 1, EmpName = "Kaff Joe" });
    emp.Add(new Employee() { EmpID = 8, DeptID = 1, EmpName = "Su Lie" });
 
Using ‘Any’ Quantifier in LINQ
This sample uses the ‘Any’ operator to list down the Departments that do not have Employees
C#
    var noEmp =
        from d in dept
        where !emp.Any(e => e.DeptID == d.DeptID)
        select new { dId = d.DeptID, dNm = d.DeptName };
 
    Console.WriteLine("Departments having no Employees");
    foreach (var empl in noEmp)
    {
        Console.WriteLine("Dept ID - " + empl.dId + ", Dept Name - " + empl.dNm);
 
    }
Output:
Any Operator
 
Using ‘Contains’ Quantifier in LINQ
The following example uses the ‘Contains’ quantifier to find the List of Departments having Employee Names starting with ‘S’
C#
     // Functionality Similar to IN operator
    var hasEmp = dept
         .Where(e => emp.Where(contact =>
         contact.EmpName.StartsWith("S"))
         .Select(d => d.DeptID)
         .Contains(e.DeptID));
 
    Console.WriteLine("/nList of Departments having Employee Names starting with S");
    foreach (var dpt in hasEmp)
    {
        Console.WriteLine("Dept ID - " + dpt.DeptID + ", Dept Name - " + dpt.DeptName);
    }
 
Output:
Contains Operator
Using ‘All’ Quantifier in LINQ
Using the ‘All’ operator, we can determine whether all employees have their names starting with ‘A’
 Console.WriteLine("Find if all Employees have their names starting with 'A'");
 bool chkName = emp.All(e =>
                    e.EmpName.StartsWith("A"));
 Console.WriteLine("Result : " + chkName);
 
 Console.ReadLine();

Output
All Operator
 
 
 
 

LINQ Examples 1

1. Example of Inner join

We will using two classes Book and Order and use the Join operator on them
class Program{
      static void Main(string[] args)
     {
           List<Book> bookList = new List<Book>
          {
                     new Book{BookID=1, BookNm="DevCurry.com Developer Tips"},
                     new Book{BookID=2, BookNm=".NET and COM for Newbies"},
                     new Book{BookID=3, BookNm="51 jQuery ASP.NET Recipes"},
                     new Book{BookID=4, BookNm="Motivational Gurus"},
                     new Book{BookID=5, BookNm="Spiritual Gurus"}
           };

           List<Order> bookOrders = new List<Order>
          {
                     new Order{OrderID=1, BookID=1, PaymentMode="Cheque"},
                     new Order{OrderID=2, BookID=5, PaymentMode="Credit"},
                     new Order{OrderID=3, BookID=1, PaymentMode="Cash"},
                     new Order{OrderID=4, BookID=3, PaymentMode="Cheque"},
                     new Order{OrderID=5, BookID=3, PaymentMode="Cheque"},
                     new Order{OrderID=6, BookID=4, PaymentMode="Cash"}
           };
      }
}

var orderForBooks = from bk in bookList
                                   join ordr in bookOrders
                                  on bk.BookID equals ordr.BookID
                                  select new
                                
{
                                          bk.BookID,
                                          Name = bk.BookNm,
                                          ordr.PaymentMode
};

foreach (var item in orderForBooks)
Console.WriteLine(item);

Console.ReadLine();

foreach (var item in orderForBooks)
Console.WriteLine(item);


LINQ join


2. Example of Left Outer join


var orderForBooks = from bk in bookList
                                   join ordr in bookOrders
                                   on bk.BookID equals ordr.BookID
                                   into a
                                   from b in a.DefaultIfEmpty(new Order())
                                   select new
                                  
{
                                             bk.BookID,
                                             Name = bk.BookNm,
                                             b.PaymentMode
                                    };
 

image


3. Aggregate Function

An aggregate function is a function where the values of multiple rows are grouped together as input on certain criteria to form a single value of greater significance or measurement such as a set. Aggregate functions return a single value.
Common Aggregate Functions are:
  • SUM() : Returns the sum of column values.
  • AVERAGE() : Returns the average of column values.
  • COUNT() : Returns the total number of rows in a table.
  • MAX() : Returns the maximum value in the column.
  • MIN() : Returns the minimum value in the column.
SELECT * FROM EMPLOYEE
Aggregate-Functions2.jpg

SUM() Function

This SUM() function returns a single value that is the result of adding all row's values for a single column or can specify a certain criteria. The SQL SUM() function takes an argument specifying which column to add all values of every row for, or some criteria for a column. In the following code I am showing the sum of salaries for an individual employee and all employees.

1. In SQL Server
SELECT SUM(SALARY) AS [TOTAL SALARY] FROM EMPLOYEE

Aggregate-Functions3.jpg
SELECT Name,SUM(SALARY) AS [SALARY] FROM EMPLOYEE GROUP BY Name

Aggregate-Functions4.jpg

2. In LINQ To SQL

private void SumGroupSalary()
{
  EmployeeOperationDataContext employee = new EmployeeOperationDataContext();

     /* Addition of salary by employee */
    var salaryEmpSum = from emp in employee.EMPLOYEEs
                           group emp by emp.Name into empg
                           select new
                           {
                               Name = empg.Key,
                               Salary = empg.Sum(x => x.SALARY)
                           };

        grdEmployee.DataSource = salaryEmpSum;
        grdEmployee.DataBind();

        /*Total Salaries for all employee */
        var salarySum = (from emp in employee.EMPLOYEEs
                         select emp.SALARY).Sum();

        Response.Write(string.Format("Addition of Salary is : {0} ", salarySum));
    }Aggregate-Functions5.jpg

AVERAGE() Function

This AVERAGE() function returns a single value that is the average of all row's values for a single column or can specify a criteria for a single column. The SQL AVG() function takes an argument specifying which column to average all values of every row for, or some criteria for a column. In the following code I am showing the average of salaries for an individual employee and all employees.

1. In SQL Server
SELECT AVG(SALARY) AS SALARY FROM EMPLOYEE Aggregate-Functions6.jpg
SELECT AVG(SALARY) AS SALARY FROM EMPLOYEE GROUP BY Name

Aggregate-Functions7.jpg

2. In LINQ To SQL

private void AverageSalary()
{
  EmployeeOperationDataContext employee = new EmployeeOperationDataContext();

        /*Averge salary from multiple salries for employee */
        var salaryGroupAvg = from emp in employee.EMPLOYEEs
                             group emp by emp.Name into empg
                             select new
                             {
                                 Name = empg.Key,
                                 Salary = empg.Average(x => x.SALARY)
                             };

        grdEmployee.DataSource = salaryGroupAvg;
        grdEmployee.DataBind();

        /*Averge of whole salary in Employee table*/
        var salaryAvg = (from emp in employee.EMPLOYEEs
                         select emp.SALARY).Average();

Response.Write(string.Format("Average of Salary is : {0} ", salaryAvg));
    }
Aggregate-Functions8.jpg

COUNT() Function

The COUNT() function returns a single value that is the count of all rows for a single column or can specify a criteria for a single column. The SQL COUNT() function takes an argument that represents which column will be used to count the total rows for or some criteria for a column. In the following code I am showing the total number employees with the same employee name and the total number of employees.

1. In SQL Server
SELECT COUNT(Id) AS [Total Number] FROM EMPLOYEE

Aggregate-Functions9.jpg
 
SELECT Name, COUNT(Id) AS [Total Number] FROM EMPLOYEE GROUP BY Name

Aggregate-Functions10.jpg

2. In LINQ To SQL
 
private void TotalNumberOfEmployee()
{
  EmployeeOperationDataContext employee = new EmployeeOperationDataContext();

        var totalEmployee = from emp in employee.EMPLOYEEs
                            group emp by emp.Name into empg
                            select new
                            {
                                Name = empg.Key,
                                TotalEmployee = empg.Count()
                            };

        grdEmployee.DataSource = totalEmployee;
        grdEmployee.DataBind();
                           
        var employeeCount = (from emp in employee.EMPLOYEEs
                         select emp.Id).Count();

        Response.Write(string.Format("Total number of Employee is : {0} ", employeeCount));
    }
Aggregate-Functions11.jpg

MAX() Function

This MAX() function returns a single value that is the maximum of all rows for a single column or can specify a criteria for a single column. The SQL MAX() function takes an argument specifying a column to get the maximum value from, or some criteria for a column. In the following code I am showing the maximum salary for an individual employee and all employees.

1. In SQL Server
SELECT MAX(SALARY) AS SALARY FROM EMPLOYEE

Aggregate-Functions12.jpg
SELECT Name, MAX(SALARY) AS SALARY FROM EMPLOYEE GROUP BY Name

Aggregate-Functions13.jpg


2. In LINQ To SQL
 
private void MaxSalary() 
{
  EmployeeOperationDataContext employee = new EmployeeOperationDataContext();

        var salaryMaximum = from emp in employee.EMPLOYEEs
                            group emp by emp.Name into empg
                            select new
                            {
                                Name = empg.Key,
                                MaximumSalary = empg.Max(x => x.SALARY)
                            };

        grdEmployee.DataSource = salaryMaximum;
        grdEmployee.DataBind();

        var salaryMax = (from emp in employee.EMPLOYEEs
                         select emp.SALARY).Max();

        Response.Write(string.Format("Maximun Salary is : {0} ", salaryMax));      

    }
Aggregate-Functions14.jpg

MIN() Function

This MIN() function returns a single value that is the minimum in all rows for a single column or can be from a specified criteria for a single column. The SQL MIN() function takes a argument that specifies a column to get the minimum value for from all rows or can be a specified criteria. In the following code I am showing the minimum salary for an individual employee and all employees.

1. In SQL Server
SELECT MIN(SALARY) AS SALARY FROM EMPLOYEE

Aggregate-Functions15.jpg
SELECT Name, MIN(SALARY) AS SALARY FROM EMPLOYEE GROUP BY Name

Aggregate-Functions16.jpg

2. In LINQ To SQL
 
private void MinSalary()
 {
  EmployeeOperationDataContext employee = new EmployeeOperationDataContext();

        /*Minimum salary per employee name */
        var salaryMinimum = from emp in employee.EMPLOYEEs
                            group emp by emp.Name into empg
                            select new
                            {
                                Name = empg.Key,
                                MinimumSalary = empg.Min(x => x.SALARY)
                            };

        grdEmployee.DataSource = salaryMinimum;
        grdEmployee.DataBind();

        /*Minimum salary in all employees */
        var salaryMin = (from emp in employee.EMPLOYEEs
                         select emp.SALARY).Min();

        Response.Write(string.Format("Minimun Salary is : {0} ", salaryMin));      

    }

Friday, 13 December 2013

LINQ Questions

1. What is LINQ?

It stands for Language Integrated Query. LINQ is collection of standard query operators
that provides the query facilities into  .NET framework language like C# , VB.NET.

2. How LINQ is beneficial than Stored Procedures?

  • Debugging - It is really very hard to debug the Stored procedure but as LINQ is part of .NET, you can use visual studio's debugger to debug the queries.
  • Deployment - With stored procedures, we need to provide an additional script for stored  procedures but with LINQ everything gets complied into single DLL hence deployment becomes easy.
  • Type Safety - LINQ is type safe, so queries errors are type checked at compile time. It is really good to encounter an error when compiling rather than runtime exception

3. Why Select clause comes after from clause in LINQ?

The reason is, LINQ is used with C# or other programming languages, which requires all the variables to be declared first. From clause of LINQ query just defines the range or conditions to select records. So that's why from clause must appear before Select in LINQ.

4. What is the extension of the file, when LINQ to SQL is used?

The extension of the file is .dbml

5. What is a Lambda expression?

A Lambda expression is nothing but an Anonymous Function, can contain expressions and statements. Lambda expressions can be used mostly to create delegates or expression tree types. Lambda expression uses lambda operator => and read as 'goes to' operator.
Left side of this operator specifies the input parameters and contains the expression or statement block at the right side.

6. What is the disadvantage of LINQ over stored procedures?

The disadvantage with LINQ is, it is not a precompiled statement where as stored procedures are precompiled.
In case of LINQ the queries need to be compile before the execution. So according to this,
I can say stored procedures are faster in performance as compared to LINQ.

7. What are Quantifiers?

They are LINQ Extension methods which return a Boolean value 
1)All
2)Any
3)Contains
4)SequenceEqual 

8. Difference between IQueryable and IEnumerable interface ?

IEnumerable

  1. IEnumerable exists in System.Collections Namespace.
  2. IEnumerable can move forward only over a collection, it can’t move backward and between the items.
  3. IEnumerable is best to query data from in-memory collections like List, Array etc.
  4. While query data from database, IEnumerable execute select query on server side, load data in-memory on client side and then filter data.
  5. IEnumerable is suitable for LINQ to Object and LINQ to XML queries.
  6. IEnumerable supports deferred execution.
  7. IEnumerable doesn’t supports custom query. 
  8. IEnumerable doesn’t support lazy loading. Hence not suitable for paging like scenarios.
  9. Extension methods supports by IEnumerable takes functional objects.

MyDataContext dc = new MyDataContext ();
IEnumerable<Employee> list = dc.Employees.Where(p => p.Name.StartsWith("S"));
list = list.Take<Employee>(10);
 
*Notice that in this query "top 10" is missing since IEnumerable filters records on client side.

IQueryable 

  1. IQueryable exists in System.Linq Namespace.
  2. IQueryable can move forward only over a collection, it can’t move backward and between the items.
  3. IQueryable is best to query data from out-memory (like remote database, service) collections.
  4. While query data from database, IQueryable execute select query on server side with all filters.
  5. IQueryable is suitable for LINQ to SQL queries.
  6. IQueryable supports deferred execution.
  7. IQueryable supports custom query using CreateQuery and Execute methods.
  8. IQueryable support lazy loading. Hence it is suitable for paging like scenarios.
  9. Extension methods supports by IEnumerable takes expression objects means expression tree.
MyDataContext dc = new MyDataContext ();
IQueryable<Employee> list = dc.Employees.Where(p => p.Name.StartsWith("S"));
list = list.Take<Employee>(10);
 
*Notice that in this query "top 10" is existing since IQueryable executes query in SQL server with all filters.

Points of Interest  

  1. IEnumerable<T> represents a forward-only cursor of T, .NET 3.5 added extension methods that included the LINQ standard query operators like Where and First, with any operators that require predicates or anonymous functions taking Func<T>.
  2. IQueryable<T> implements the same LINQ standard query operators, but accepts Expression<Func<T>> for predicates and anonymous functions. Expression<T> is a compiled expression tree, a broken-up version of the method ("half-compiled" if you will) that can be parsed by the queryable's provider and used accordingly.

9. What is the difference between FirstOrDefault() and SingleOrDefault() extension method in LINQ ?

FirstOrDefault() = gets the first item that matches a given criteria. 
SingleOrDefault() = if you specify this extension method that means you are specifically saying that there can be only one value that matches the criteria. If there are more then 1 value that matches the criteria, throw an exception.

10. What is the difference between First() and Single() extension methods in LINQ ?

• First() - There is at least one result, an exception is thrown if no result is returned. 
• Single() - There is exactly 1 result, no more, no less, an exception is thrown if no result is returned.

11. Write a query to get the single employee name when there are many employees whose name is "test" in the database ?

var employee = (from h in contextobject.Employee
                where h.EmployeeName == "test"
                select h).FirstOrDefault<Employee>();

12. Write a query to get the list of all employees whose name is "test" ?

var employeeList = (from h in context.Employee
                    where h.EmployeeName == "test"
                    select h).ToList<Employee>();

13. What are the three main components of LINQ or Language Integrated Query?

1. Standard Query Operators
2. Language Extensions
3. LINQ Providers

14. How are Standard Query Operators useful in LINQ?

Standard Query Operators in LINQ can be used for working with collections for any of the following and more.
1. Get total count of elements in a collection.
2. Order the results of a collection.
3. Grouping.
4. Computing average.
5. Joining two collections based on matching keys.
6. Filter the results

15. List the important language extensions made in C# to make LINQ a reality?

1. Implicitly Typed Variables
2. Anonymous Types
3. Object Initializers
4. Lambda Expressions

16. What are the four LINQ Providers that .NET Framework ships?

1. LINQ to Objects - Executes a LINQ query against a collection of objects
2. LINQ to XML - Executes an XPATH query against XML documents
3. LINQ to SQL - Executes LINQ queries against Microsoft SQL Server.
4. LINQ to DataSets - Executes LINQ queries against ADO.NET DataSets.