Thursday, May 24, 2012

LINQPad

string[] names = {"Michael", "Long"};

IEnumerable<string> query = names
.Where(n=>n.Contains("o"))
.OrderBy(n=>n.Length)
.Select(n=>n.ToUpper());

query.Dump();

// same query as above
IEnumerable<string>filtered = names.Where(n=>n.Contains("o"));
IEnumerable<string>sorted = filtered.OrderBy(n=>n.Length);
IEnumerable<string>finalQuery = sorted.Select(n=>n.ToUpper());

filtered.Dump("Filtered");
sorted.Dump("Sorted");
finalQuery.Dump("FinalQuery");

LINQ Dynamic Query

using System.Linq.Dynamic

var repository = new EmployeeRepository();

var query = repository.GetAll()
.AsQueryable()
.OrderBy("Name")
.Where("DepartmentID = 1");

LINQ Joins


var employeeRepository = new EmployeeRepository();
var departmentRepository = new DepartmentRepository();

Inner Join (Normal)

var employees =
from employee in employeeRepository.GetAll()
join department in departmentRepository.GetAll()
on employee.DepartmentID equals department.ID
select new {employee.Name, Department = department.Name};

Left Join (Grouping on Departments)

var query =
from d in departmentRepository.GetAll()
join e in employeesRepository.GetAll()
on d.ID equals e.DepartmentID
into ed
select new
{
Department = d.Name,
Employees = ed};

foreach(var group in query)
{
Console.WriteLine(group.Department);
foreach(var employee in group.Employees)
{
Console.WriteLine("\t" + employee.Name);
}
}

Cross Join (for completeness)


var employees =
from employee in employeeRepository.GetAll()
join department in departmentRepository.GetAll()
on employee.DepartmentID equals department.ID
select new {employee.Name, Department = department.Name};

LINQ Grouping and Projecting

var repository = new EmployeeRepository();

Comprehensive Query Syntax

var queryByDepartment =
from e in repository.GetAll()
group e by e.DepartmentID
into eGroup
orderby eGroup.Key descending
where eGroup.Key < 3
select new
{
DepartmentID = eGroup.Key,
Count = eGroup.Count(),
Employees = eGroup
};

Extension Methods with Lambda Expressions

var queryByDepartment2 =
repository.GetAll()
.GroupBy(e=>e.DepartmentID)
.OrderByDescending(g=>g.Key)
.Where(g=>g.Key < 3)
.Select(g=>
new
{
DepartmentID = g.Key,
Count = g.Count(),
Employees = g
});

foreach(var group in queryByDepartment2)
{
Console.WriteLine("DID: {0}, Count: {1}",
group.DepartmentID,
group.Count);

foreach(var employee in group.Employees)
{
Console.WriteLine("\t{0}:{1}", employee.DepartmentID, employee.Name);
}
}

Restrictions for Implicit Typing

The following var statements result in compiler errors:

var i;

var j, k = 0;

var n = null;

var number = "2";
int x = number + 1;

Extension Methods with Lambda Expressions vs. Comprehensive Query Syntax

Employee[] employees = new Employee[]
{
new Employee{ID=1, Name="The"},
new Employee{ID=2, Name="Foo"}
};

//Employee the = Array.Find(employees, FindThePredicate);
Employee the = Array.Find(employees, e=>e.Name == "The");

Comprehensive Query Syntax

Collection

IEnumerable<Employee> query1 =
from e in employees
where e.Name == "The"
orderby e.ID ascending
select e;

Single Item

Employee query1 =
(from e in employees
where e.Name == "The"
orderby e.ID ascending
select e).First();

Extension Methods with Lambda Expressions

Collection

IEnumerable<Employee> query2 =
employees.Where(e=>e.Name=="The")
.OrderBy(e=>e.ID)
.Select(e=>e);

Single Item

Employee query2 =
employees.Where(e=>e.Name=="The")
.OrderBy(e=>e.ID)
.Select(e=>e)
.First();

Action and Func Delegates and Lambda Expressions

private static void ActionAndFunc()
{
Action printEmptyLine = () => Console.WriteLine();
Action<int> printNumber = x => Console.WriteLine(x);
Action<int, int> printTwoNumbers = (x,y) =>
{
Console.WriteLine(x);
Console.WriteLine(y);
};

Func<DateTime> getTime = () => DateTime.Now;
Func<int, int> square = x => x*x;
Func<int, int, int> multiply = (x,y) => x*y;

printEmptyLine();
printNumber(6);
printTwoNumbers(2,3);

DateTime now = getTime();
int z = multiply(4,7);
}

Wednesday, May 23, 2012

Named vs. Anonymous Method vs. Lambda Expressions

Named Method Predicate - passing method pointers

static void Main(string[] args)
{
Employee the = Array.Find(employees, FindThePredicate);
}

static bool FindThePredicate(Employee e)
{
return e.Name == "The";
}

Anonymous Method

static void Main(string[] args)
{
Employee the = Array.Find(employees,
delegate(Employee e)
{
return e.Name == "The";
}
);
}

Lambda Expression - anonymous method but with less code

static void Main(string[] args)
{
Employee the = Array.Find(employees, (e) => e.Name =="The");
}