Exceptions in C#:

What: Exception is an unusual situation that an application may come across while its execution.

If a user (programmer) do not provide a mechanism to handle these anomalies, the .NET run time environment provide a default mechanism, which terminates the program execution. 

.NET Framework provides several classes to work with exceptions. When there is an exception, the .NET framework creates an object of type ‘Exception’ and ‘throws’ it. This Exception object contains all information about the ‘error’.

System.Exception: Exception class provides a set of properties & methods that help finding out the reason behind the exception raised, identify the source object that has raised the exception, the stack tracing which contains the information regarding the order of method call prior to the raise of exception, the innerException proper maintains the causal relationship exists between two or more exceptions. The HelpLink property can hold a URL to a help page.

 

Exception Handling:

1. Try-Catch-Finally:

C# provides three Keywords try, catch and finally to do exception handling. The try encloses the statements that might throw an exception whereas catch handles an exception if one exists. The finally can be used for doing any clean up process.


try
{
// Statement which can cause an exception.
}
catch(Type x)
{
// Statements for handling the exception
}
finally
{
//Any cleanup code
}

Uncaught Exceptions: If the raised runtime anomaly can’t find any suitable catch block or any new exception re-thrown out of the caught catch block, this exception will proceed further to next level.

2. Page_Error: The next level to the “try-catch” block is Page_Error which will catch the unhandled exceptions at page level.


public void Page_Error(object sender, EventArgs e)

        {

            Exception ex = Server.GetLastError();

            string errorDetails = “Error Occured at :” + Request.Url.ToString() +

                                  “<br><b>Error Message:” + ex.Message +

                                  “<br><b>Stack Trace :” + ex.StackTrace;

            // some code to log this error

            //————————-

           

            Context.Server.ClearError();//Code to clear the exception to stop the exception passing to Application level

        } 

     

        protected void Page_Load(object sender, EventArgs e)

        {

            int a = 100;

            int b = 0;

            float c = a / b;//divide by Zero exception will be thrown here

           

        }

 

The line “context.server.clearError ()” will clear the raised Exception. So there is no progression of exception from this level to further Application_Error.

3. Application_Error:

The Application_Error event handler is specified in the Global.asax file of our application.

If the Exceptions which are not handled (caught) using catch block, and not cleared (context.server.clearError ()) in Page_Error event, those will be raised further to Application_Error event handler.


  protected void Application_Error(object sender, EventArgs e)

        {

            Exception ex = Server.GetLastError();

            string errorDetails = “Error Occured at :” + Request.Url.ToString() +

                                  “<br><b>Error Message:” + ex.Message +

                                  “<br><b>Stack Trace :” + ex.StackTrace;

            // some code to log this error

            //————————-

 

            Context.Server.ClearError();//Code to clear the exception to stop the exception being handled by CustomErrors in web.config

 

        }

 

4. CustomErrors in Web.Config: If you do not call Server.ClearError or trap the error in the Page_Error or Application_Error event handler, the error is handled based on the settings in the <customErrors> section of the Web.config file. In the <customErrors> section, you can specify a redirect page as a default error page (defaultRedirect) or specify to a particular page based on the HTTP error code that is raised. You can use this way to customize the error message that the user receives. If an error occurs that is not trapped at any of the previous levels in your application, this custom error page is displayed.


<authentication mode=Windows/>

                        <customErrors mode=On defaultRedirect=Error.aspx>

                                    <error statusCode=404 redirect=PageNotFound.aspx/>                                  

                        </customErrors>

Notice that the <customErrors> section includes a mode attribute that is set to on. The mode attribute is used to control how the error redirection occurs. For example, if you are developing the application, you most likely want to see the actual ASP.NET error messages and do not want to be redirected to the more user-friendly error page. The mode attribute includes the following settings:

  • On: Unhandled exceptions redirect the user to the specified defaultRedirect page. This mode is used mainly in production.
  • Off: Users receive the exception information and are not redirected to the defaultRedirect page. This mode is used mainly in development.
  • RemoteOnly: Only users who access the site on the local computer (by using localhost) receive the exception information. All other users are redirected to the defaultRedirect page. This mode is used mainly for debugging.

When & Why: Among Try-Catch, Page_Error, Application_Error and CustomErrors, we go for each type based on the particular requirement.

  • Generally we include try-catch blocks in our code which has threat of exceptions.
  • In order to catch the unhandled exceptions (uncaught) we either go for Page level or application level exception handling. Here, if we need to log any page specific variables along with the exception details, we go for Page_Error. Otherwise let go the exceptions being handled at Application level using Application_Error. Page redirection to custom error pages can also be done at this level using Response.Redirect
  • If we want to catch the URL specific/Page not found exception i.e. the user enters incorrect URL, we go for CustomErrors in web.config.

 

 

Advertisements

SqlBulkCopy:

 

When:

If we have large data in the DataTable/DataReader object and need to perform insertion into the database physical table, we can use this SqlBulkCopy class.

When the order of the columns in In-Memory table differs with the Physical Database table columns, using this sql bulk copy, column mappings can be done easily.

In the situations like uploading the huge amounts of data through files, we will store the data being read from the file in In-Memory table. Sql Bulk copy can be used to insert this In-Memory data to database physical table.

Why:

By performing a bulk copy it could be possible to reduce the number of database accesses to improve performance and speed.

How:

SqlBulkCopy:

SqlBulkCopy is the object that helps you to perform a bulk copy.  You can use a DataReader or DataTable as source and copy them to a destination table in database. To accomplish this task, SqlBulkCopy uses a collection of SqlBulkCopyColumnMapping objects which will be saved as its SqlBulkCopyColumnMappingCollection property.  SqlBulkCopyColumnMapping maps a column in data source to a table in destination table via their name or index. SqlBulkCopy has some important properties that you should be aware of them to be able to use it:

  • BatchSize: Number of rows in each batch. At the end of each batch, the rows in the batch are sent to the server. This value has direct effect on the number of accesses to database. Zero (the default) indicates that each WriteToSever operation is a single batch.
  • BulkCopyTimeOut: Number of seconds for the operation to complete before it times out. If the operation does time out, the transaction is not committed and all copied rows are removed from the destination table.
  • ColumnMappings: A ReadOnly SqlBulkCopyColumnMappingCollection.  You need to use its Add () method to add a new SqlBulkCopyColumnMapping object to its collection.
  • DestinationTableName: String value of destination table’s name.
  • NotifyAfter: SqlRowsCopied event handler will be called when the number of rows specified in this property has been copied. 

This object also has four overloads. You can pass a SqlConnection (or a connection string) plus an optional SqlBulkCopyOptions and SqlTransaction to its constructor.  Latest two parameters can change the behavior of SqlBulkCopy object.  Using SqlBulkCopyOptions enumerator you can specify that for example SqlBulkCopy keeps identities or check constraints and some other options. Using SqlTransaction you can pass an external SqlTransaction and your SqlBulkCopy uses this transaction in all parts of the process.

SqlBulkCopy also has a SqlRowsCopied event handler that triggers when the specific number of DataRows that have been copies.  You specified this value via NotifyAfter property.  This handler is helpful when you want to be aware of your process (for instance showing it via a ProgressBar to end user).

The last thing that should be mentioned about SqlBulkCopy object is its WriteToServer () method.  This method can get an array of DataRows, a DataTable or a DataReader and copies their content to destination table in database.

SqlBulkCopyColumnMapping

SqlBulkCopyColumnMapping is the object that maps your source columns to destination columns in a bulk copy.  A SqlBulkCopyColumnMapping can get the source and destination column names or ordinals via its properties or its constructor.  It has these properties:

· SourceColumn: String value of source column’s name.

· SourceOrdinal: Integer value of source column’s index.

· DestinationColumn: String value of destination column’s name.

· DestinationOrdinal: Integer value of destination column’s index.

One of SourceColumn and SourceOrdinal and one of DestinationColumn and DestinationOrdinal should be set.  Also you can set these properties via constructor which is an easier way.

Note that if your source and destination columns have same names, it’s not required to use SqlBulkCopyColumnMapping objects because SqlBulkCopy can do its job automatically.

Sample Application:

I’ll try to demonstrate this SqlBulkCopy class via an example application. I’ll try to create an In Memory table by manually filling the data. Next I try to insert this In-Memory table data to Database table “Employee”.


 protected void Page_Load(object sender, EventArgs e)

        {

            DataTable InMemoryTable = null;

            InMemoryTable = new DataTable();

            //Filling the In-Memory Table

            InMemoryTable.Columns.Add(“EmployeeNo”);

            InMemoryTable.Columns.Add(“EmployeeName”);

            InMemoryTable.Columns.Add(“EmployeeSalary”);

            InMemoryTable.Rows.Add(1, “xxx”, 1000);

            InMemoryTable.Rows.Add(2, “yyy”, 2000);

            InMemoryTable.Rows.Add(3, “zzz”, 3000);

            InMemoryTable.Rows.Add(4, “ppp”, 2000);

            InMemoryTable.Rows.Add(5, “qqq”, 3000);

            InMemoryTable.Rows.Add(6, “rrr”, 1000);

            InMemoryTable.Rows.Add(7, “sss”, 2000);

 

            //SqlBulkCopy object creation

            SqlBulkCopy sBulk = new SqlBulkCopy(“server=.;TrustedConnection=true;database=MDS”);

 

            //Column Mappings

            SqlBulkCopyColumnMapping colMap1 = new SqlBulkCopyColumnMapping(“EmployeeNo”, “ENo”);

            SqlBulkCopyColumnMapping colMap2 = new SqlBulkCopyColumnMapping(“EmployeeName”, “EName”);

            SqlBulkCopyColumnMapping colMap3 = new SqlBulkCopyColumnMapping(“EmployeeSalary”, “ESal”);

            //Initialising the properties of SqlBulkCopy object

            sBulk.BatchSize = 6;

            sBulk.BulkCopyTimeout = 60;

            sBulk.DestinationTableName = “Employee”;

            sBulk.NotifyAfter = 6;

            sBulk.SqlRowsCopied += new SqlRowsCopiedEventHandler(sBulk_SqlRowsCopied);

            //Adding the column mappings

            sBulk.ColumnMappings.Add(colMap1);

            sBulk.ColumnMappings.Add(colMap2);

            sBulk.ColumnMappings.Add(colMap3);

            //writing to Database physical table

            sBulk.WriteToServer(InMemoryTable);

 

 

        }

       

        // Event which will be fired once the rows=Notify After has been inserted

        void sBulk_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e)

        {

            Response.Write(“Copied {0} so far…”+e.RowsCopied);

 

        }

           

 

 

Grouping Operators in Linq:

Let’s explore the various Grouping operations in Linq using ‘group by’ in both Query syntax & Method Syntax Format with the help of following program.

The Employee & Department are the Classes created for the demo purpose.


public class Employee

   {

      public int EmpNo;

      public string EmpName;

      public float salary;

      public int DeptNo;

      public int[] Reportees;//list of the emp-id’s of reportees

      public Employee(int eno, string Ename, float sal, int No,int[] r)

       {

            EmpNo = eno; EmpName = Ename; salary = sal; DeptNo = DNo;

            Reportees = r;

       }

    }

 

    public class Department

    {

        public int DeptNo;

        public string DeptName;

        public Department(int dno, string dname)

        {

            DeptNo = dno;DeptName = dname;

        }

    }

 


static void Main(string[] args)

        {          

            List<Department> dList = new List<Department>();

            dList.Add(new Department(1, “Tech Lead”));

            dList.Add(new Department(2, “Project Lead”));

            dList.Add(new Department(3, “Module Lead”));

            List<Employee> EmpList = new List<Employee>();

            EmpList.Add(new Employee(1, “ppp”, 100, 1, new

            int[]{2,3,4,5,6}));

            EmpList.Add(new Employee(2, “qqq”, 70, 2, new

            int[]{3,4,5,6}));

            EmpList.Add(new Employee(3, “rrr”, 50, 3, new

            int[]{4,5,6}));

            EmpList.Add(new Employee(4, “xxx”, 100, 1, new

            int[]{5,6}));

            EmpList.Add(new Employee(5, “yyy”, 100, 1, new int[]{6}));

            EmpList.Add(new Employee(6, “zzz”, 50, 3, new int[]{}));

            // different queries of type – Grouping

            // In the Query syntax & method syntax

            //1. Simple Group by

            var q1 = from e1 in EmpList

                     group e1 by e1.DeptNo;

            q1 = EmpList.GroupBy(e1 => e1.DeptNo);

 

            var q2 = from e1 in EmpList

                      group e1 by e1.DeptNo into g

                      select new { DeptNo = g.Key, Emp = g };

            q2 = EmpList.GroupBy(e1 => e1.DeptNo).Select(g => new

                 {DeptNo=g.Key,Emp=g });

 

            //2. Simple Group by & ordering the resulted groups on

            // deptno basis

            var q3 = from e1 in EmpList

                     group e1 by e1.DeptNo into g

                     orderby g.Key

                     select g;

            q3 = EmpList.GroupBy(e1 => e1.DeptNo).OrderBy(g => g.Key);

 

            //3.selecting only few coloumns from the grouped data

            var q4 = from e1 in EmpList

                     group e1 by e1.DeptNo into g

                     select new { count = g.Count(), deptNo = g.Key };

            q4 = EmpList.GroupBy(e1 => e1.DeptNo).Select(g => new {

                 count = g.Count(), deptNo = g.Key });

     

 

            //4.Filtering the data before grouping

            var q5 = from e1 in EmpList

                     where e1.EmpNo < 6

                     group e1 by e1.DeptNo into g

                     select g;

            q5 = EmpList.Where(e1 => e1.EmpNo < 6).GroupBy(e1 =>

                 e1.DeptNo);

 

            //5.Filtering the groups (after grouping)

            var q6 = from e1 in EmpList

                     group e1 by e1.DeptNo into g

                     where g.Key==1

                     select new {Deptno=g.Key,Count=g.Count()};

            q6 = EmpList.GroupBy(e1 => e1.DeptNo).Where(g => g.Key ==

                 1).Select(g => new { Deptno = g.Key, Count = g.Count()

                 });

 

            //6.Group By Multiple values

            var q7 = from e1 in EmpList

                     group e1 by (new { e1.EmpName, e1.DeptNo }) into g

                     select

            new{Dno=g.Key.DeptNo,Ename=g.Key.EmpName,count=g.Count()};              

        }

 

Ordering Operators :

We use order by operator to display the objects in the sorted order. Default sorting order is ‘ascending’. If we want to sort in descending order, we can mention it explicitly.

The Employee & Department are the Classes created for the demo purpose.

public class Employee

   {

      public int EmpNo;

      public string EmpName;

      public float salary;

      public int DeptNo;

      public int[] Reportees;//list of the emp-id’s of reportees

      public Employee(int eno, string Ename, float sal, int No,int[] r)

       {

            EmpNo = eno; EmpName = Ename; salary = sal; DeptNo = DNo;

            Reportees = r;

       }

    }

 

    public class Department

    {

        public int DeptNo;

        public string DeptName;

        public Department(int dno, string dname)

        {

            DeptNo = dno;DeptName = dname;

        }

    }

 

static void Main(string[] args)

        {          

            List<Department> dList = new List<Department>();

            dList.Add(new Department(1, “Tech Lead”));

            dList.Add(new Department(2, “Project Lead”));

            dList.Add(new Department(3, “Module Lead”));

            List<Employee> EmpList = new List<Employee>();

            EmpList.Add(new Employee(1, “ppp”, 100, 1, new

            int[]{2,3,4,5,6}));

            EmpList.Add(new Employee(2, “qqq”, 70, 2, new

            int[]{3,4,5,6}));

            EmpList.Add(new Employee(3, “rrr”, 50, 3, new

            int[]{4,5,6}));

            EmpList.Add(new Employee(4, “xxx”, 100, 1, new

            int[]{5,6}));

            EmpList.Add(new Employee(5, “yyy”, 100, 1, new int[]{6}));

            EmpList.Add(new Employee(6, “zzz”, 50, 3, new int[]{}));

            // different queries of type – ordering

            // In the Query syntax & method syntax

            //1.Order By – ordering by one field in ascending order

            var q1 = from e1 in EmpList

                     orderby e1.EmpName

                     select e1;

            q1 = EmpList.OrderBy(e1 => e1.EmpName);

 

            //2.Order By – ordering by one field in descending order

            var q2 = from e1 in EmpList

                     orderby e1.EmpName descending

                     select e1;

            q2 = EmpList.OrderByDescending(e1 => e1.EmpName);

 

 

            //3.Order By – ordering by two field in ascending order

            var q3 = from e1 in EmpList

                     orderby e1.DeptNo, e1.EmpName

                     select e1;

            q3 = EmpList.OrderBy(e1 => e1.DeptNo).ThenBy(e1 =>

                 e1.EmpName);

 

 

            //4.Order By – ordering by two field in descending order

            var q4 = from e1 in EmpList

                     orderby e1.DeptNo, e1.EmpName

                     select e1;

            q4 = EmpList.OrderByDescending(e1 =>

                 e1.DeptNo).ThenByDescending(e1 => e1.EmpName);

 

            //5.Reverse

            var q5 = (from e1 in EmpList

                      select e1).Reverse();

                  

        }

About ‘ThenBy’ keyword:

ThenBy is one of the ordering query operators available in linq. We can use ThenBy operator with linq to objects, linq to XML and linq to SQL. We use ThenBy operator to do secondary sort when writing queries in  method syntax. ThenBy operator is used to sort by more than 1 property. When we want to sort initially we would start with using the orderby operator. Since orderby operator returns IOrderderedEnumerable<T>,we cannot reuse the orderby operator again because it can be only used on sequences that implement IEnumerable<T>.  This is where the ThenBy operator comes into play. ThenBy operator is an extension method that is available on input sequence that implement IOrderededEnumerable<T> and also returns IOrderedEnumerable<T> which allows you to reuse it multiple times if you want to sort by more than 1 column or property. 

Partitioning Operators in Linq:

Lets explore the various partitioning operations in Linq using Take, TakeWhile, Skip, SkipWhile in both Query syntax & Method Syntax Format with the help of following program.

The Employee & Department are the Classes created for the demo purpose.


public class Employee

   {

      public int EmpNo;

      public string EmpName;

      public float salary;

      public int DeptNo;

      public int[] Reportees;//list of the emp-id’s of reportees

      public Employee(int eno, string Ename, float sal, int No,int[] r)

       {

            EmpNo = eno; EmpName = Ename; salary = sal; DeptNo = DNo;

            Reportees = r;

       }

    }

 

    public class Department

    {

        public int DeptNo;

        public string DeptName;

        public Department(int dno, string dname)

        {

            DeptNo = dno;DeptName = dname;

        }

    }

 


static void Main(string[] args)

        {          

            List<Department> dList = new List<Department>();

            dList.Add(new Department(1, “Tech Lead”));

            dList.Add(new Department(2, “Project Lead”));

            dList.Add(new Department(3, “Module Lead”));

            List<Employee> EmpList = new List<Employee>();

            EmpList.Add(new Employee(1, “ppp”, 100, 1, new

            int[]{2,3,4,5,6}));

            EmpList.Add(new Employee(2, “qqq”, 70, 2, new

            int[]{3,4,5,6}));

            EmpList.Add(new Employee(3, “rrr”, 50, 3, new

            int[]{4,5,6}));

            EmpList.Add(new Employee(4, “xxx”, 100, 1, new

            int[]{5,6}));

            EmpList.Add(new Employee(5, “yyy”, 100, 1, new int[]{6}));

            EmpList.Add(new Employee(6, “zzz”, 50, 3, new int[]{}));

            // different queries of type – Partitioning

            // In the Query syntax & method syntax

            //Take

            //1.Collecting first 2 employee’s objects

            var q1 = (from e1 in EmpList

                      select e1).Take(2);

             q1 = EmpList.Take(2);

           

            //2.Collecting first 2 employee’s of department id=1

            var q2 =(from e1 in EmpList

                     where e1.DeptNo == 1

                     select e1).Take(2);           

             q2 = EmpList.Where(e1 =&gt; e1.DeptNo = 1).Take(2);

 

            //Skip

            //3.Collects all but first 2 employee’s

             var q3 =( from e1 in EmpList

                      select e1).Skip(2);

             q3 = EmpList.Skip(2);

 

            //4.Skips first record of employee whose department id=1

             var q4 =(from e1 in EmpList

                      where e1.DeptNo == 1

                      select e1).Skip(1);

             q4 = EmpList.Where(e1 =>e1.DeptNo = 1).Skip(1);

 

 

            //5.TakeWhile-used to take records from starting to the

            //point where condition on an object is hit

            //collects all the records untill employee name becomes

            //’xxx’

            var q5 = (from e1 in EmpList

                      select e1).TakeWhile(e1=>e1.EmpName!=“xxx”);

            q5 = EmpList.TakeWhile(e1 =>e1.EmpName != “xxx”);

 

            //6.SkipWhile-used to Skip records from starting to the

            // point where condition on an object is hit

            //Skips all the records untill employee name becomes ‘xxx’

             var q6 = (from e1 in EmpList

                      select e1).SkipWhile(e1=>e1.EmpName!=“xxx”);

             q6 = EmpList.SkipWhile(e1 => e1.EmpName != “xxx”);

                  

        }

 

 

 

 

Restriction Operators :

Lets explore the various Restriction operations in Linq using ‘where’ in both Query syntax & Method Syntax Format with the help of following program.

The Employee & Department are the Classes created for the demo purpose.


public class Employee

   {

      public int EmpNo;

      public string EmpName;

      public float salary;

      public int DeptNo;

      public int[] Reportees;//list of the emp-id’s of reportees

      public Employee(int eno, string Ename, float sal, int No,int[] r)

       {

            EmpNo = eno; EmpName = Ename; salary = sal; DeptNo = DNo;

            Reportees = r;

       }

    }

 

    public class Department

    {

        public int DeptNo;

        public string DeptName;

        public Department(int dno, string dname)

        {

            DeptNo = dno;DeptName = dname;

        }

    }

 


static void Main(string[] args)

        {          

            List<Department> dList = new List<Department>();

            dList.Add(new Department(1, “Tech Lead”));

            dList.Add(new Department(2, “Project Lead”));

            dList.Add(new Department(3, “Module Lead”));

            List<Employee> EmpList = new List<Employee>();

            EmpList.Add(new Employee(1, “ppp”, 100, 1, new

            int[]{2,3,4,5,6}));

            EmpList.Add(new Employee(2, “qqq”, 70, 2, new

            int[]{3,4,5,6}));

            EmpList.Add(new Employee(3, “rrr”, 50, 3, new

            int[]{4,5,6}));

            EmpList.Add(new Employee(4, “xxx”, 100, 1, new

            int[]{5,6}));

            EmpList.Add(new Employee(5, “yyy”, 100, 1, new int[]{6}));

            EmpList.Add(new Employee(6, “zzz”, 50, 3, new int[]{}));

          // different queries of type – Restriction

          // In the Query syntax & method syntax

          //1.Filtering based on DeptNo

            var q1 = from e1 in EmpList

                     where e1.DeptNo==1

                     select e1;

            q1=EmpList.Where(e1=>e1.DeptNo==1).Select(e1=>e1);

          //2.Filtering the Employees whose name starts with ‘p’

            var q2 = from e1 in EmpList

                     where e1.EmpName.StartsWith(“p”)

                     select e1;

            q2=EmpList.Where(e1=>e1.EmpName.StartsWith(“p”));

 

          //3.Index in where condition

            var q3 = EmpList.Where((e1, i) => e1.EmpName.Length ==

                     i);                      

 

        }

 

 

Projection Operators in Linq:

Lets explore the various projection operations in Linq using ‘select’ & ‘selectmany’ in both Query syntax & Method Syntax Format with the help of following program.

The Employee & Department are the Classes created for the demo purpose.


public class Employee

   {

      public int EmpNo;

      public string EmpName;

      public float salary;

      public int DeptNo;

      public int[] Reportees;//list of the emp-id’s of reportees

      public Employee(int eno, string Ename, float sal, int No,int[] r)

       {

            EmpNo = eno; EmpName = Ename; salary = sal; DeptNo = DNo;

            Reportees = r;

       }

    }

 

    public class Department

    {

        public int DeptNo;

        public string DeptName;

        public Department(int dno, string dname)

        {

            DeptNo = dno;DeptName = dname;

        }

    }

 


static void Main(string[] args)

       {          

            List<Department> dList = new List<Department>();

            dList.Add(new Department(1, “Tech Lead”));

            dList.Add(new Department(2, “Project Lead”));

            dList.Add(new Department(3, “Module Lead”));

            List<Employee> EmpList = new List<Employee>();

            EmpList.Add(new Employee(1, “ppp”, 100, 1, new

            int[]{2,3,4,5,6}));

            EmpList.Add(new Employee(2, “qqq”, 70, 2, new

            int[]{3,4,5,6}));

            EmpList.Add(new Employee(3, “rrr”, 50, 3, new

            int[]{4,5,6}));

            EmpList.Add(new Employee(4, “xxx”, 100, 1, new

            int[]{5,6}));

            EmpList.Add(new Employee(5, “yyy”, 100, 1, new int[]{6}));

            EmpList.Add(new Employee(6, “zzz”, 50, 3, new int[]{}));

          // different queries of type – Projection

          // In the Query syntax & method syntax

          //1.selecting all the list of employee objects

            var q1 = from e1 in EmpList

                     select e1;

            q1 = EmpList.Select(e1=>e1);           

 

          //2.selecting only required field from Employee list

          //objects

            var q2 = from e1 in EmpList

                     select e1.EmpNo;

            q2 = EmpList.Select(e1 => e1.EmpNo);

 

          //3.Select – transformation Data- selecting all the yearly

          //salaries of all employees

            var q3 = from e1 in EmpList

                     select e1.salary * 12;

            q3 = EmpList.Select(e1 => e1.salary * 12);

 

          //4.Select – Anonymous types

            var q4 = from e1 in EmpList

                     select new { EmployeeNo = e1.EmpNo, AnnuualSalary

                     = e1.salary * 12 };

            q4 = EmpList.Select(e1 => new { EmployeeNo = e1.EmpNo,

                 AnnuualSalary = e1.salary * 12 });

 

 

          //5.Select – Anonymous types

            var q5 = from e1 in EmpList

                     join d1 in dList on e1.DeptNo equals d1.DeptNo

                     select new { EmployeeNo = e1.EmpNo,

                     DepartmentName=d1.DeptName };           

 

          //6.Select – Indexed

          //checking whether employee object index = employee id

            var q6=EmpList.Select((e1, index) => new { Num = e1.EmpNo,

                   InPlace = (e1.EmpNo == index) });

 

          //7.Select – Collection from more than one list

          //collects lists from both the lists ie..picks each value in

          //1st list & evaluates against all values in the 2nd list

            var q7 = from e1 in EmpList

                     from d1 in dList

                     where e1.DeptNo == d1.DeptNo

                     select new {e1.EmpNo,d1.DeptName };           

           

          //8.Select – querying the inner object

          //selecting all the reportees of all the employee’s

            var q8 = from e1 in EmpList

                     from r in e1.Reportees

                     select new {ManagerName=e1.EmpName,ReporteeId=r };

            q8 = EmpList.SelectMany(e1 => e1.Reportees.Select(r => new

                 {ManagerName=e1.EmpName,ReporteeId=r }));

 

          //9.Select – querying the inner object with a condition

          //selecting all the managers for the reportee id=2

            var q9 = from e1 in EmpList

                     from r in e1.Reportees

                     where r==2

                     select new { ManagerName = e1.EmpName, ReporteeId

                     = r };

            q9 = EmpList.SelectMany(e1 => e1.Reportees.Where(r => r ==

                 2).Select(r => new { ManagerName = e1.EmpName,

                 ReporteeId = r }));

 

          //10.Filtering on the outer as well inner object

          //selecting the managers of the reportee with id=6 & mangers

          //who are from deptid=1,2

            var q10 = from e1 in EmpList

                      where e1.DeptNo==1 || e1.DeptNo==2

                      from r in e1.Reportees

                      where r == 6

                      select new { ManagerName = e1.EmpName, ReporteeId

                      = r };

            q10 = EmpList.Where(e => e.DeptNo == 1 || e.DeptNo ==

                  2).SelectMany(e1 => e1.Reportees.Where(r => r ==

                  6).Select(r => new { ManagerName = e1.EmpName,

                  ReporteeId = r }));

 

           

          //11.SelectMany

            var q11 = EmpList.SelectMany((e1, i) =>

                      e1.Reportees.Select(r => i+1 + “)employee Name :”

                      + e1.EmpName + ” has reportee with id =” + r));

                      q11 = EmpList.SelectMany(e1 =>

                      e1.Reportees.Select(r => r.ToString()));

          //12.Selecting the First result object out of selected

          //collection

            var q12 = (from e1 in EmpList

                       select e1.EmpName).FirstOrDefault();

                      

 

        }