Search This Blog

Tuesday, August 21, 2018

LINQ (Language Integrated Query) - PART - 2


Topics Included:
#GroupBy   #FirstOrDefault  #LastOrDefault  #ElementAtOrDefault  #SingleOrDefault  #DefaultIfEmpty  #GroupJoin  #INNERJOIN  #LEFTOUTERJOIN  #Distinct  #Intersect  #Except  #Range  #Repeat  #Empty  #Concat  #SequenceEqual  #All  #ANY  #Contains 



#GroupBy


GroupBy operator belong to Grouping Operators category. This operator takes a flat sequence of items, organize that sequence into groups (IGrouping<K,V>) based on a specific key and return groups of sequences.

In short, GroupBy creates and returns a sequence of IGrouping<K,V>

E.G. 1)
var employeeGroup = from employee in Employee.GetAllEmployees()
                    group employee by employee.Department;

foreach (var group in employeeGroup)
{
    Console.WriteLine("{0} - {1}", group.Key, group.Count());
}


E.G. 2)
var employeeGroup = from employee in Employee.GetAllEmployees()
                                      group employee by employee.Department;

foreach (var group in employeeGroup)
{
    Console.WriteLine("{0} - {1}", group.Key, group.Count());
    Console.WriteLine("----------");
    foreach (var employee in group)
    {
        Console.WriteLine(employee.Name + "\t" + employee.Department);
    }
    Console.WriteLine(); Console.WriteLine();
}

E.G. 3)
var employeeGroup = from employee in Employee.GetAllEmployees()
                                      group employee by employee.Department into eGroup
                                      orderby eGroup.Key
                                      select new
                                      {
                                           Key = eGroup.Key,
                                           Employees = eGroup.OrderBy(x => x.Name)
                                      };

foreach (var group in employeeGroup)
{
    Console.WriteLine("{0} - {1}", group.Key, group.Employees.Count());
    Console.WriteLine("----------");
    foreach (var employee in group.Employees)
    {
        Console.WriteLine(employee.Name + "\t" + employee.Department);
    }
    Console.WriteLine(); Console.WriteLine();
}

Group by multiple keys

roup employees by Department and then by Gender. The employee groups should be sorted first by Department and then by Gender in ascending order. Also, employees within each group must be sorted in ascending order by Name.


var employeeGroups = Employee.GetAllEmployees()
.GroupBy(x => new { x.Department, x.Gender })
.OrderBy(g => g.Key.Department).ThenBy(g => g.Key.Gender)
.Select(g => new
{
    Dept = g.Key.Department,
    Gender = g.Key.Gender,
    Employees = g.OrderBy(x => x.Name)
});



Element Operators

Element Operators retrieve a single element from a sequence using the element index or based on a condition. All of these methods have a corresponding overloaded version that accepts a predicate.

#First

There are 2 overloaded versions of this method. The first overloaded version that does not have any parameters simply returns the first element of a sequence.

E.G. 1: Returns the first element from the sequence
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int result = numbers.First();
Console.WriteLine("Result = " + result);

Output:
Result = 1

If the sequence does not contain any elements, then First() method throws an InvalidOperationException.

E.G. 2: Throws InvalidOperationException.
int[] numbers = { };
int result = numbers.First();
Console.WriteLine("Result = " + result);

Output:
Unhandled Exception: System.InvalidOperationException: Sequence contains no elements

The second overloaded version is used to find the first element in a sequence based on a condition. If the sequence does not contain any elements or if no element in the sequence satisfies the condition then an InvalidOperationException is thrown.

E.G. 3: Returns the first even number from the sequence
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int result = numbers.First(x => x % 2 == 0);
Console.WriteLine("Result = " + result);

Output:
Result = 2

E.G. 4: Throws InvalidOperationException, as no element in the sequence satisfies the condition specified by the predicate.
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int result = numbers.First(x => x % 2 == 100);
Console.WriteLine("Result = " + result);

Output:
Unhandled Exception: System.InvalidOperationException: Sequence contains no matching element

#FirstOrDefault

This is very similar to First, except that this method does not throw an exception when there are no elements in the sequence or when no element satisfies the condition specified by the predicate. Instead, a default value of the type that is expected is returned. For reference types the default is NULL and for value types the default depends on the actual type expected.

E.G. 5: Returns ZERO. No element in the sequence satisfies the condition, so the default value (ZERO) for int is returned.
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int result = numbers.FirstOrDefault(x => x % 2 == 100);
Console.WriteLine("Result = " + result);

Last : Very similar to First, except it returns the last element of the sequence.

#LastOrDefault

Very similar to FirstOrDefault, except it returns the last element of the sequence.

ElementAt : Returns an element at a specified index. If the sequence is empty or if the provided index value is out of range, then an ArgumentOutOfRangeException is thrown.

E.G. 6: Returns element from the sequence that is at index position 1.
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int result = numbers.ElementAt(1);
Console.WriteLine("Result = " + result);

Output:
Result = 2

E.G. 7: Throws ArgumentOutOfRangeException
int[] numbers = { };
int result = numbers.ElementAt(0);
Console.WriteLine("Result = " + result);

Output:
Unhandled Exception: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.

#ElementAtOrDefault

Similar to ElementAt except that this method does not throw an exception, if the sequence is empty or if the provided index value is out of range. Instead, a default value of the type that is expected is returned.

#Single

There are 2 overloaded versions of this method. The first overloaded version that does not have any parameters returns the only element of the sequence.

E.G. 8: Returns the only element (1) of the sequence.
int[] numbers = { 1 };
int result = numbers.Single();
Console.WriteLine("Result = " + result);

Output:
Result = 1

Single() method throws an exception if the sequence is empty or has more than one element.

E.G. 9: Throws InvalidOperationException as the sequence contains more than ONE element.
int[] numbers = { 1, 2 };
int result = numbers.Single();
Console.WriteLine("Result = " + result);

Output:
Unhandled Exception: System.InvalidOperationException: Sequence contains more than one element

The second overloaded version of the Single() method is used to find the only element in a sequence that satisfies a given condition. An exception will be thrown if any of the following is true
a) If the sequence does not contain any elements OR
b) If no element in the sequence satisfies the condition OR
c) If more than one element in the sequence satisfies the condition

E.G. 10: Throws InvalidOperationException as more than one element in the sequence satisfies the condition
int[] numbers = { 1, 2, 4 };
int result = numbers.Single(x => x % 2 == 0);
Console.WriteLine("Result = " + result);

Output:
Unhandled Exception: System.InvalidOperationException: Sequence contains more than one matching element

#SingleOrDefault

Very similar to Single(), except this method does not throw an exception when the sequence is empty or when no element in the sequence satisfies the given condition. Just like Single(), this method will still throw an exception, if more than one element in the sequence satisfies the given condition.

E.G. 11: Throws InvalidOperationException as more than one element in the sequence satisfies the given condition
int[] numbers = { 1, 2, 4 };
int result = numbers.SingleOrDefault(x => x % 2 == 0);
Console.WriteLine("Result = " + result);

Output:
Unhandled Exception: System.InvalidOperationException: Sequence contains more than one matching element

#DefaultIfEmpty

If the sequence on which this method is called is not empty, then the values of the original sequence are returned.

E.G. 12: Returns a copy of the original sequence
int[] numbers = { 1, 2, 3 };
IEnumerable<int> result = numbers.DefaultIfEmpty();
foreach (int i in result)
{
    Console.WriteLine(i);
}

Output:
1
2
3

If the sequence is empty, then DefaultIfEmpty() returns a sequence with the default value of the expected type.

E.G. 13: Since the sequence is empty, a sequence containing the default value (ZERO) of int is returned.
int[] numbers = { };
IEnumerable<int> result = numbers.DefaultIfEmpty();
foreach (int i in result)
{
    Console.WriteLine(i);
}

Output:
0

The other overloaded version with a parameter allows us to specify a default value. If this method is called on a sequence that is not empty, then the values of the original sequence are returned. If the sequence is empty, then this method returns a sequence with the specified defualt value.

E.G. 14: Since the sequence is empty, a sequence containing the specified default value (10) is returned.
int[] numbers = { };
IEnumerable<int> result = numbers.DefaultIfEmpty(10);
foreach (int i in result)
{
    Console.WriteLine(i);
}

Output:
10



#GroupJoin


Group Join produces hierarchical data structures. Each element from the first collection is paired with a set of correlated elements from the second collection.

public class Department
{
    public int ID { get; set; }
    public string Name { get; set; }

    public static List<Department> GetAllDepartments()
    {
        return new List<Department>()
        {
            new Department { ID = 1, Name = "IT"},
            new Department { ID = 2, Name = "HR"},
            new Department { ID = 3, Name = "Payroll"},
        };
    }
}

public class Employee
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int DepartmentID { get; set; }

    public static List<Employee> GetAllEmployees()
    {
        return new List<Employee>()
        {
            new Employee { ID = 1, Name = "Mark", DepartmentID = 1 },
            new Employee { ID = 2, Name = "Steve", DepartmentID = 2 },
            new Employee { ID = 3, Name = "Ben", DepartmentID = 1 },
            new Employee { ID = 4, Name = "Philip", DepartmentID = 1 },
            new Employee { ID = 5, Name = "Mary", DepartmentID = 2 },
            new Employee { ID = 6, Name = "Valarie", DepartmentID = 2 },
            new Employee { ID = 7, Name = "John", DepartmentID = 1 },
            new Employee { ID = 8, Name = "Pam", DepartmentID = 1 },
            new Employee { ID = 9, Name = "Stacey", DepartmentID = 2 },
            new Employee { ID = 10, Name = "Andy", DepartmentID = 1}
        };
    }
}

E.G. 1: Group employees by Department.
var employeesByDepartment = Department.GetAllDepartments()
   .GroupJoin(Employee.GetAllEmployees(),
     d => d.ID,
     e => e.DepartmentID,
     (department, employees) => new
     {
         Department = department,
         Employees = employees
     });

foreach (var department in employeesByDepartment)
{
    Console.WriteLine(department.Department.Name);
    foreach (var employee in department.Employees)
    {
        Console.WriteLine(" " + employee.Name);
    }
    Console.WriteLine();
}

E.G. 2: Rewrite Example 1 using SQL Like Query syntax.
var employeesByDepartment = from d in Department.GetAllDepartments()
           join e in Employee.GetAllEmployees()
           on d.ID equals e.DepartmentID into eGroup
           select new
           {
              Department = d,
              Employees = eGroup
           };

Note: Group Join uses the join operator and the into keyword to group the results of the join.

#INNER JOIN 


If you have 2 collections, and when you perform an inner join, then only the matching elements between the 2 collections are included in the result set. Non - Matching elements are excluded from the result set.

E.G. 1:
 var result = Employee.GetAllEmployees().Join(Department.GetAllDepartments(),
            e => e.DepartmentID,
            d => d.ID, (employee, department) => new
            {
                EmployeeName = employee.Name,
                DepartmentName = department.Name
            });


E.G. 2: Rewrite Example 1 using SQL Like Query syntax.
var result = from e in Employee.GetAllEmployees()
        join d in Department.GetAllDepartments()
        on e.DepartmentID equals d.ID
        select new
        {
            EmployeeName = e.Name,
            DepartmentName = d.Name
        };

#LEFT OUTER JOIN


With INNER JOIN only the matching elements are included in the result set. Non-matching elements are excluded from the result set.

With LEFT OUTER JOIN all the matching elements + all the non matching elements from the left collection are included in the result set

Use DefaultIfEmpty() method on the results of a group join to implement Left Outer Join

E.G. 1: Implement a Left Outer Join between Employees and Department collections and print all the Employees and their respective department names. Employees without a department, should display "No Department" against their name.
var result = from e in Employee.GetAllEmployees()
                    join d in Department.GetAllDepartments()
                    on e.DepartmentID equals d.ID into eGroup
                    from d in eGroup.DefaultIfEmpty()
                    select new
                    {
                         EmployeeName = e.Name,
                         DepartmentName = d == null ? "No Department" : d.Name
                    };


E.G. 2: Rewrite Example 1 using extension method syntax.
var result = Employee.GetAllEmployees()
                        .GroupJoin(Department.GetAllDepartments(),
                                e => e.DepartmentID,
                                d => d.ID,
                                (emp, depts) => new { emp, depts })
                        .SelectMany(z => z.depts.DefaultIfEmpty(),
                                (a, b) => new
                                {
                                        EmployeeName = a.emp.Name,
                                        DepartmentName = b == null ? "No Department" : b.Name
                                });

To implement Left Outer Join, with extension method syntax we use the GroupJoin() method along with SelectMany() and DefaultIfEmpty() methods.

#Distinct


var result = countries.Distinct();
var result = countries.Distinct(StringComparer.OrdinalIgnoreCase);

#Union


var result = numbers1.Union(numbers2);

#Intersect


var result = numbers1.Intersect(numbers2);

#Except


var result = numbers1.Except(numbers2);



Generation Operators

#Range


var evenNumbers = Enumerable.Range(1, 10).Where(x => x % 2 == 0);

#Repeat


var result = Enumerable.Repeat("Hello", 5);

#Empty


IEnumerable<int> result = GetIntegerSequence() ?? Enumerable.Empty<int>();

Here we are using NULL-COALESCING operator that checks if the GetIntegerSequence() method returns NULL, in which case the result variable is initialized with an empty IEnumerable<int>.



#Concat


var result = numbers1.Concat(numbers2);

Difference between Concat and Union operators

Concat operator combines 2 sequences into 1 sequence. Duplicate elements are not removed. It simply returns the items from the first sequence followed by the items from the second sequence.

Union operator also combines 2 sequences into 1 sequence, but will remove the duplicate elements.

#SequenceEqual


SequenceEqual() method is used to determine whether two sequences are equal. This method returns true if the sequences are equal otherwise false.

For 2 sequences to be equal
1. Both the sequences should have same number of elements and
2. Same values should be present in the same order in both the sequences

E.G. 1: SequenceEqual() returns true.

string[] countries1 = { "USA", "India", "UK" };
string[] countries2 = { "USA", "India", "UK" };

var result = countries1.SequenceEqual(countries2);

E.G. 2: In this case, SequenceEqual() returns false, as the default comparison is case sensitive.

string[] countries1 = { "USA", "INDIA", "UK" };
string[] countries2 = { "usa", "india", "uk" };

var result = countries1.SequenceEqual(countries2);

Console.WriteLine("Are Equal = " + result);

E.G. 3: If we want the comparison to be case insensitive, then use the other overloaded version of SequenceEqual() method to which we can pass an alternate comparer.

string[] countries1 = { "USA", "INDIA", "UK" };
string[] countries2 = { "usa", "india", "uk" };

var result = countries1.SequenceEqual(countries2, StringComparer.OrdinalIgnoreCase);


E.G. 4: SequenceEqual() returns false. This is because, although both the sequences contain same data, the data is not present in the same order.

string[] countries1 = { "USA", "INDIA", "UK" };
string[] countries2 = { "UK", "INDIA", "USA" };

var result = countries1.SequenceEqual(countries2);

Console.WriteLine("Are Equal = " + result);

E.G. 5: To fix the problem in Example 4, use OrderBy() to sort data in the source sequences.

string[] countries1 = { "USA", "INDIA", "UK" };
string[] countries2 = { "UK", "INDIA", "USA" };

var result = countries1.OrderBy(c =] c).SequenceEqual(countries2.OrderBy(c =] c));



Quantifiers 


#All()

method returns true if all the elements in a sequence satisfy a given condition, otherwise false.

Example 1 : Returns true, as all the numbers are less than 10

int[] numbers = { 1,2,3,4,5 };

var result = numbers.All(x =] x [ 10);

#ANY()


There are 2 overloaded versions of Any() method. The version without any parameters checks if the sequence contains at least one element. The other version with a predicate parameter checks if the sequence contains at least one element that satisfies a given condition.

int[] numbers = { 1,2,3,4,5 };

var result = numbers.Any();

#Contains()


There are 2 overloaded versions of the Contains() method. One of the overloaded version checks if the sequence contains a specified element using the default equality comparer. The other overloaded version checks if the sequence contains a specified element using an alternate equality comparer.

Returns true as the sequence contains number 3. In this case the default equality comparer is used.

int[] numbers = { 1,2,3,4,5 };

var result = numbers.Contains(3);




LINQ PAD Download

https://www.linqpad.net/Download.aspx




LINQ (Language Integrated Query) - PART - 1

Topics Included:

#Min   #Max  #Sum  #Count  #Average  #WHERE  #INDEX  #And  #Or  #SelectMany  #Distinct
#OrderBy  #ThenBy  #Reverse  #Take  #Skip  #TakeWhile  #SkipWhile  #Deferred  #Immediate
#ToDictionary  #ToLookUp  #Cast  #OfType 





  • LINQ enables us to query any type of data store (SQL Server, XML documents, Objects in memory etc). 
  • LINQ enables us to work with these different data sources using a similar coding style without having the need to know the syntax specific to the data source.
  • LINQ provides intellisense and compile time error checking.

There are 2 ways to write LINQ queries-
1) Using SQL like query expressions

select
from
where
orderby
join
groupby

The Standard Query Operators are implemented as extension methods on IEnumerable<T> interface.

E.G. 1)
IEnumerable<Student> students = from student in Student.GetAllStudents()
                                                           where student.Gender == "Male"
                                                           select student;

E.G. 2)
IEnumerable<int> evenNumbers = from num in numbers
                                                           where num % 2 == 0
                                                           select num;


2) Using Lambda Expressions.

E.G. 1)
IEnumerable<Student> students = Student.GetAllStudents()
    .Where(student => student.Gender == "Male");

E.G. 2)
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            IEnumerable<int> evenNumbers = numbers.Where(num => num % 2 == 0);


Aggregate Function

int[] Numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };


#Min()


int smallestNumber = Numbers.Min();
int smallestEvenNumber = Numbers.Where(n => n % 2 == 0).Min();

#Max()


int largestNumber = Numbers.Max();
int largestEvenNumber = Numbers.Where(n => n % 2 == 0).Max();

#Sum()


int sumOfAllNumbers = Numbers.Sum();
int sumOfAllEvenNumbers = Numbers.Where(n => n % 2 == 0).Sum();

#Count()


int countOfAllNumbers = Numbers.Count();
int countOfAllEvenNumbers = Numbers.Where(n => n % 2 == 0).Count();

#Average()


double averageOfAllNumbers = Numbers.Average();
double averageOfAllEvenNumbers = Numbers.Where(n => n % 2 == 0).Average();

E.G. 1)
string[] countries = { "India", "USA", "UK" };

int minCount = countries.Min(x => x.Length);
int maxCount = countries.Max(x => x.Length);

E.G. 2)
string[] countries = { "India", "US", "UK", "Canada", "Australia" };

string result = countries.Aggregate((a, b) => a + ", " + b);

E.G. 3)
int[] Numbers = { 2, 3, 4, 5 };

int result = Numbers.Aggregate((a, b) => a * b);



#WHERE



IEnumerable<int> evenNumbers = numbers.Where(num => num % 2 == 0);

Can be rewritten as shown below

Func<int, bool> predicate = i => i % 2 == 0;
IEnumerable<int> evenNumbers = numbers.Where(predicate);

#INDEX Value



List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

E.G. - Lambda Expression
IEnumerable<int> evenNumberIndexPositions = numbers
    .Select((num, index) => new { Number = num, Index = index })
    .Where(x => x.Number % 2 == 0)
    .Select(x => x.Index);

#AND



IEnumerable<Department> departments = context.Departments
                .Where(dept => dept.Name == "IT" && dept.Name == "HR");

#OR



IEnumerable<Department> departments = context.Departments
                .Where(dept => dept.Name == "IT" || dept.Name == "HR");


#SelectMany



E.G. - Lambda Expression
IEnumerable<string> allSubjects = Student.GetAllStudetns().SelectMany(s => s.Subjects);

E.G. - SQL Like Query
IEnumerable<string> allSubjects = from student in Student.GetAllStudetns()
                                from subject in student.Subjects
                                select subject;

E.G.
string[] stringArray =
{
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
    "0123456789"
};

E.G - Lambda Expression
IEnumerable<char> result = stringArray.SelectMany(s => s);

E.G - SQL Like Query
IEnumerable<char> result = from s in stringArray
                           from c in s
                           select c;

#Distinct



E.G - Lambda Expression
IEnumerable<string> allSubjects = Student.GetAllStudetns().SelectMany(s => s.Subjects).Distinct();                                                                                                         

E.G - SQL Like Query
IEnumerable<string> allSubjects = (from student in Student.GetAllStudetns()
                                                             from subject in student.Subjects
                                                             select subject).Distinct();


Difference between Select and SelectMany

Select and select Many can fetch the same data but in selectMany we can return a IEnumerable string where as select we can return list of IEnmerable list of string so too many loops can be used (at least two). By using SelectMany we can reduce nested loop

#OrderBy



E.G - Lambda Expression
IEnumerable<Student> result = from student in Student.GetAllStudents()
                                                      orderby student.Name
                                                      select student;
E.G - Lambda Expression
IEnumerable<Student> result = Student.GetAllStudents().OrderByDescending(s => s.Name);

E.G - SQL Like Query
IEnumerable<Student> result = from student in Student.GetAllStudents()
                                                      orderby student.Name descending
                                                      select student;

#ThenBy



OrderBy or OrderByDescending performs the primary sort. #ThenBy or

#ThenByDescending

is used for adding secondary sort. Secondary Sort operators (ThenBy or ThenByDescending ) can be used more than once in the same LINQ query.

E.G - Lambda Expression
IEnumerable<Student> result = Student.GetAllStudetns()
    .OrderBy(s => s.TotalMarks).ThenBy(s => s.Name).ThenBy(s => s.StudentID);

E.G - SQL Like Query
IEnumerable<Student> result = from student in Student.GetAllStudetns()
                                                      orderby student.TotalMarks, student.Name, student.StudentID
                                                      select student;

#Reverse



IEnumerable<Student> result = students.Reverse();


#Take, Skip, TakeWhile & SkipWhile

string[] countries = { "Australia", "Canada", "Germany", "US", "India", "UK", "Italy" };

#Take



Take method returns a specified number of elements from the start of the collection. The number of items to return is specified using the count parameter this method expects.

IEnumerable<string> result = countries.Take(3);

IEnumerable<string> result = (from country in countries select country).Take(3);

#Skip



Skip method skips a specified number of elements in a collection and then returns the remaining elements. The number of items to skip is specified using the count parameter this method expects.

Note: For the same argument value, the Skip method returns all of the items that the Take method would not return.

IEnumerable<string> result = countries.Skip(3);


#TakeWhile



TakeWhile method returns elements from a collection as long as the given condition specified by the predicate is true.

IEnumerable<string> result = countries.TakeWhile(s => s.Length > 2);


#SkipWhile



SkipWhile method skips elements in a collection as long as the given condition specified by the predicate is true, and then returns the remaining elements.

IEnumerable<string> result = countries.SkipWhile(s => s.Length > 2);


Paging using Skip and Take

int PageSize = 3
IEnumerable<student> result = students.Skip((pageNumber - 1) * PageSize).Take(PageSize);



Query Type

#Deferred & Immediate



LINQ operators can be broadly classified into 2 categories based on the behaviour of query execution
1. #Deferred or Lazy Operators -  These query operators use deferred execution.
Examples - select, where, Take, Skip etc
2. #Immediate or Greedy Operators - These query operators use immediate execution.
Examples - count, average, min, max, ToList etc

List<Student> listStudents = new List<Student>
{
    new Student { StudentID= 101, Name = "Tom", TotalMarks = 800 },
    new Student { StudentID= 102, Name = "Mary", TotalMarks = 900 },
    new Student { StudentID= 103, Name = "Pam", TotalMarks = 800 }
};

// LINQ Query is only defined here and is not executed at this point
// If the query is executed at this point, the result should not display Tim
IEnumerable<Student> result = from student in listStudents
                              where student.TotalMarks == 800
                              select student;

// Add a new student object with TotalMarks = 800 to the source
listStudents.Add(new Student { StudentID = 104, Name = "Tim", TotalMarks = 800 });

// The above query is actually executed when we iterate thru the sequence
// using the foreach loop. This is proved as Tim is also included in the result
foreach (Student s in result)
{
    Console.WriteLine(s.StudentID + "\t" + s.Name + "\t" + s.TotalMarks);
}

Immediate

// Since we are using ToList() which is a greedy operator
// the LINQ Query is executed immediately at this point
            IEnumerable<Student> result = (from student in listStudents
                                           where student.TotalMarks == 800
                                           select student).ToList();

// Since we are using Count() operator, the LINQ Query is executed at this point
            int result = (from student in listStudents
                          where student.TotalMarks == 800

                          select student).Count();



#ToDictionary



Please Note: Keys in the dictionary must be unique. If two identical keys are created by the keySelector function, the following System.ArgumentException will be thrown at runtime.
Unhandled Exception: System.ArgumentException: An item with the same key has already been added.

List<Student> listStudents = new List<Student>
{
    new Student { StudentID= 101, Name = "Tom", TotalMarks = 800 },
    new Student { StudentID= 102, Name = "Mary", TotalMarks = 900 },
    new Student { StudentID= 103, Name = "Pam", TotalMarks = 800 }
};

Dictionary<int, Student> result = listStudents.ToDictionary(x => x.StudentID);

foreach (KeyValuePair<int, Student> kvp in result)
{
    Console.WriteLine(kvp.Key + "\t" + kvp.Value.Name + "\t" + kvp.Value.TotalMarks);
}

#ToLookUp



ToLookup creates a Lookup. Just like a dictionary, a Lookup is a collection of key/value pairs. A dictionary cannot contain keys with identical values, where as a Lookup can.

var employeesByJobTitle = listEmployees.ToLookup(x => x.JobTitle);

Console.WriteLine("Employees Grouped By JobTitle");
foreach (var kvp in employeesByJobTitle)
{
    Console.WriteLine(kvp.Key);
    // Lookup employees by JobTitle
    foreach (var item in employeesByJobTitle[kvp.Key])
    {
        Console.WriteLine("\t" + item.Name + "\t" + item.JobTitle + "\t" + item.City);
    }
}



Conversion Operator

#Cast



Cast operator attempts to convert all of the items within an existing collection to another type and return them in a new collection. If an item fails conversion an exception will be thrown. This method uses deferred execution.

ArrayList list = new ArrayList();
list.Add(1);
list.Add(2);
list.Add(3);

// The following item causes an exception
// list.Add("ABC");

IEnumerable<int> result = list.Cast<int>();

#OfType



OfType operator will return only elements of the specified type. The other type elements are simply ignored and excluded from the result set.


ArrayList list = new ArrayList();
list.Add(1);
list.Add(2);
list.Add(3);
list.Add("4");
list.Add("ABC");

IEnumerable<int> result = list.OfType<int>();


Difference Between Cast And OfType Operators

OfType operator returns only the elements of the specified type and the rest of the items in the collection will be ignored and excluded from the result.

Cast operator will try to cast all the elements in the collection into the specified type. If some of the items fail conversion, InvalidCastException will be thrown.


When to use Cast over OfType and vice versa?
We would generally use Cast when the following 2 conditions are met
1. We want to cast all the items in the collection &
2. We know for sure the collection contains only elements of the specified type

If we want to filter the elements and return only the ones of the specified type, then we would use OfType. 

Monday, August 20, 2018

Extension Methods - C#

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C#, F# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.

In other word, Extension methods, as the name suggests, are additional methods. Extension methods allow you to inject additional methods without modifying, deriving or recompiling the original class, struct or interface. Extension methods can be added to your own custom class, .NET framework classes, or third party classes or interfaces.

In the following example, IsGreaterThan() is an extension method for int type, which returns true if the value of the int variable is greater than the supplied integer parameter.

Example: Extension Method
int i = 10;

bool result = i.IsGreaterThan(100); //returns false 

The IsGreaterThan() method is not a method of int data type (Int32 struct). It is an extension method written by the programmer for the int data type. The IsGreaterThan() extension method will be available throughout the application by including the namespace in which it has been defined.

Now let's see how to write an extension method.

Example: Define an Extension Method
namespace ExtensionMethods
{
    public static class IntExtensions
     {
        public static bool IsGreaterThan(this int i, int value)
        {
            return i > value;
        }
    }
}


Now, you can include the ExtensionMethods namespace wherever you want to use this extension method.

Example: Extension method
using ExtensionMethods;

class Program
{
    static void Main(string[] args)
    {
        int i = 10;

        bool result = i.IsGreaterThan(100);

        Console.WriteLine(result);
    }
}

How to use extension methods?

An extension method is a static method of a static class, where the "this" modifier is applied to the first parameter. The type of the first parameter will be the type that is extended.

Note:
The only difference between a regular static method and an extension method is that the first parameter of the extension method specifies the type that it is going to operator on, preceded by the this keyword.

Points to Remember :

  • Extension methods are additional custom methods which were originally not included with the class.
  • Extension methods can be added to custom, .NET Framework or third party classes, structs or interfaces.
  • The first parameter of the extension method must be of the type for which the extension method is applibable, preceded by the this keyword.
  • Extension methods can be used anywhere in the application by including the namespace of the extension method.

Regular Expression - C#

Metacharacter Description
. Find a single character, except newline or line terminator
\w Find a word character
\W Find a non-word character
\d Find a digit
\D Find a non-digit character
\s Find a whitespace character
\S Find a non-whitespace character
\b Find a match at the beginning/end of a word
\B Find a match not at the beginning/end of a word
\0 Find a NUL character
\n Find a new line character



Pattern Description
^ Start at the beginning of the string.
\s* Match zero or more white-space characters.
[\+-]? Match zero or one occurrence of either the positive sign or the negative sign.
\s? Match zero or one white-space character.
\$? Match zero or one occurrence of the dollar sign.
\s? Match zero or one white-space character.
\d* Match zero or more decimal digits.
\.? Match zero or one decimal point symbol.
\d{2}? Match two decimal digits zero or one time.
(\d*\.?\d{2}?){1} Match the pattern of integral and fractional digits separated by a decimal point symbol at least one time.
$ Match the end of the string.


Quantifier Description
n+ Matches any string that contains at least one n
n* Matches any string that contains zero or more occurrences of n
n? Matches any string that contains zero or one occurrences of n
n{X} Matches any string that contains a sequence of X n's
n{X,Y} Matches any string that contains a sequence of X to Y n's
n{X,} Matches any string that contains a sequence of at least X n's
n$ Matches any string with n at the end of it
^n Matches any string with n at the beginning of it
?=n Matches any string that is followed by a specific string n
?!n Matches any string that is not followed by a specific string n


Expression Description
[abc] Find any character between the brackets
[^abc] Find any character NOT between the brackets
[0-9] Find any character between the brackets (any digit)
[^0-9] Find any character NOT between the brackets (any non-digit)
(x|y) Find any of the alternatives specified (X or Y)
{3} Lengh of 3
{3,6} Length between 3 to 6
[0-9A-Z] Match an alphanumeric character. The part number must consist of at least this character.
[-.\w]* Match zero or more occurrences of any word character, hyphen, or period.
\$ Match a dollar sign.
(?<=[0-9A-Z]) Look ahead of the ending dollar sign to ensure that the previous character is alphanumeric.
[.?:;!] Match a period, question mark, colon, semicolon, or exclamation point.


Example Pattern
Email ^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$
WebSite ^http(s)?://([\w-]+.)+[\w-]+(/[\w- ./?%&=])?$
Password ^(?=.*[A-Z].*[A-Z])(?=.*[!@#$&*])(?=.*[0-9].*[0-9])(?=.*[a-z].*[a-z].*[a-z]).{8}$
Cheat Code
Character
Description
\ Marks the next character as either a special character or escapes a literal. For example, "n" matches the character "n". "\n" matches a newline character. The sequence "\\" matches "\" and "\(" matches "(".
Note: double quotes may be escaped by doubling them: "<a href=""...>"
^ Depending on whether the MultiLine option is set, matches the position before the first character in a line, or the first character in the string.
$ Depending on whether the MultiLine option is set, matches the position after the last character in a line, or the last character in the string.
* Matches the preceding character zero or more times. For example, "zo*" matches either "z" or "zoo".
+ Matches the preceding character one or more times. For example, "zo+" matches "zoo" but not "z".
? Matches the preceding character zero or one time. For example, "a?ve?" matches the "ve" in "never".
. Matches any single character except a newline character.
(pattern) Matches pattern and remembers the match. The matched substring can be retrieved from the resulting Matches collection, using Item [0]...[n]. To match parentheses characters ( ), use "\(" or "\)".
(?<name>pattern) Matches pattern and gives the match a name.
(?:pattern) A non-capturing group
(?=...) A positive lookahead
(?!...) A negative lookahead
(?<=...) A positive lookbehind .
(?<!...) A negative lookbehind .
x|y Matches either x or y. For example, "z|wood" matches "z" or "wood". "(z|w)oo" matches "zoo" or "wood".
{n} n is a non-negative integer. Matches exactly n times. For example, "o{2}" does not match the "o" in "Bob," but matches the first two o's in "foooood".
{n,} n is a non-negative integer. Matches at least n times. For example, "o{2,}" does not match the "o" in "Bob" and matches all the o's in "foooood." "o{1,}" is equivalent to "o+". "o{0,}" is equivalent to "o*".
{n,m} m and n are non-negative integers. Matches at least n and at most m times. For example, "o{1,3}" matches the first three o's in "fooooood." "o{0,1}" is equivalent to "o?".
[xyz] A character set. Matches any one of the enclosed characters. For example, "[abc]" matches the "a" in "plain".
[^xyz] A negative character set. Matches any character not enclosed. For example, "[^abc]" matches the "p" in "plain".
[a-z] A range of characters. Matches any character in the specified range. For example, "[a-z]" matches any lowercase alphabetic character in the range "a" through "z".
[^m-z] A negative range characters. Matches any character not in the specified range. For example, "[m-z]" matches any character not in the range "m" through "z".
\b Matches a word boundary, that is, the position between a word and a space. For example, "er\b" matches the "er" in "never" but not the "er" in "verb".
\B Matches a non-word boundary. "ea*r\B" matches the "ear" in "never early".
\d Matches a digit character. Equivalent to [0-9].
\D Matches a non-digit character. Equivalent to [^0-9].
\f Matches a form-feed character.
\k A back-reference to a named group.
\n Matches a newline character.
\r Matches a carriage return character.
\s Matches any white space including space, tab, form-feed, etc. Equivalent to "[ \f\n\r\t\v]".
\S Matches any nonwhite space character. Equivalent to "[^ \f\n\r\t\v]".
\t Matches a tab character.
\v Matches a vertical tab character.
\w Matches any word character including underscore. Equivalent to "[A-Za-z0-9_]".
\W Matches any non-word character. Equivalent to "[^A-Za-z0-9_]".
\num Matches num, where num is a positive integer. A reference back to remembered matches. For example, "(.)\1" matches two consecutive identical characters.
\n Matches n, where n is an octal escape value. Octal escape values must be 1, 2, or 3 digits long. For example, "\11" and "\011" both match a tab character. "\0011" is the equivalent of "\001" & "1". Octal escape values must not exceed 256. If they do, only the first two digits comprise the expression. Allows ASCII codes to be used in regular expressions.
\xn Matches n, where n is a hexadecimal escape value. Hexadecimal escape values must be exactly two digits long. For example, "\x41" matches "A". "\x041" is equivalent to "\x04" & "1". Allows ASCII codes to be used in regular expressions.
\un Matches a Unicode character expressed in hexadecimal notation with exactly four numeric digits. "\u0200" matches a space character.
\A Matches the position before the first character in a string. Not affected by the MultiLine setting
\Z Matches the position after the last character of a string. Not affected by the MultiLine setting.
\G Specifies that the matches must be consecutive, without any intervening non-matching characters.












Sunday, August 19, 2018

Html 5

Evolution history of HTML by timeline


XHTML

Before starting little bit discuss about XHTML first.

EXtensible HyperText Markup Language

  • stricter than HTML
  • DOCTYPE is mandatory
  • <html>, <head>, <title>, and <body> are mandatory
  • Elements must be properly nested, properly closed and in lower case
  • Attribute names must be in lower case, Attribute values must be quoted, Attribute minimization is forbidden

Wrong:
<input type="checkbox" name="vehicle" value="car" checked />
Correct:
<input type="checkbox" name="vehicle" value="car" checked="checked" />

How to Convert from HTML to XHTML

  • Add an XHTML <!DOCTYPE> to the first line of every page
  • Add an xmlns attribute to the html element of every page
  • Change all element names to lowercase
  • Close all empty elements
  • Change all attribute names to lowercase
  • Quote all attribute values

HTML5

Basically HTML5 has it’s many new syntactical features, which include the <video>, <audio>, and <canvas> elements, as well as the integration of SVG content. Due to these new elements, it will be very easy to integrate multimedia and graphical content to the web without using flash and third party plugins. There are also another new elements like <section>, <article>, <header> and <nav> which enrich the semantic value of the document.

The most interesting new API's in HTML5 are:

HTML Geolocation
HTML Drag and Drop
HTML Local Storage
HTML Application Cache
HTML Web Workers
HTML SSE

Important Tags

<details>
  <summary>Copyright 1999-2018.</summary>
  <p> - by Refsnes Data. All Rights Reserved.</p>
  <p>All content and graphics on this web site are the property of the company Refsnes Data.</p>
</details>

<header>

<footer>

<nav>

<progress>

<audio controls>
  <source src="horse.mp3" type="audio/mpeg">
</audio>

<embed src="helloworld.swf">

<video width="320" height="240" controls>
  <source src="movie.mp4" type="video/mp4">
</video>

Input Types

<input type="text" name="firstname" value="Mickey" id="name">
<input type="password">
<input type="submit" value="Submit">
<input type="reset">
<input type="radio" name="gender" value="male" checked>
<input type="checkbox" name="vehicle1" value="Bike">
<input type="button" onclick="alert('Hello World!')" value="Click Me!">

HTML 5
<input type="color" name="favcolor">
<input type="date" name="bday">
<input type="date" name="bday" max="2018-08-30" min="2018-08-01">
<input type="email" name="email">
<input type="month" name="bdaymonth">
<input type="number" name="quantity" min="1" max="5">
<input type="range" name="points" min="0" max="10">
<input type="search" name="googlesearch">
<input type="tel" name="usrtel">
<input type="time" name="usr_time">
 <input type="url" name="homepage">
 <input type="week" name="week_year">

Input Type Attributes

<input type="text" name="firstname" value="John">
<input type="text" name="firstname" value="John" readonly>
<input type="text" name="firstname" value="John" disabled>
<input type="text" name="firstname" value="John" size="40">
<input type="text" name="firstname" maxlength="10">

HTML 5
The novalidate attribute is a <form> attribute.
When present, novalidate specifies that the form data should not be validated when submitted.
<form action="/action_page.php" novalidate>

<input type="text" name="fname" autofocus>

<input type="email" name="email" autocomplete="off">

<form action="/action_page.php" method="get">

<form action="/action_page_binary.asp" method="post">

<input type="submit" formtarget="_blank" value="Submit to a new window">

<input type="image" src="img_submit.gif" alt="Submit" width="48" height="48">

<input list="browsers" name="browser">
<datalist id="browsers">
  <option value="Internet Explorer">
  <option value="Firefox">
  <option value="Chrome">
  <option value="Opera">
  <option value="Safari">
</datalist>

<input type="number" name="quantity" min="1" max="5">
<input type="text" name="country_code" pattern="[A-Za-z]{3}" title="Three letter country code">
<input type="text" name="fname" placeholder="First name">
<input type="text" name="usrname" required>
<input type="number" name="points" step="3">