Out of the box LINQ provides approximately 50 standard query operators:-
- Filtering (e.g. where)
- Projection (e.g. select. Projection returns just some data attributes in an object/table, not all)
- Joining
- Partitioning (skip, take. Useful for pagination e.g. give me results 11-20).
- Ordering (order by)
- Aggregating (group by)
The same standard operators work everywhere. There are additionally custom query operators / providers produced by the user community (e.g. LINQ to Amazon).
- LINQ to SQL supports SQL Server only. LINQ to entities provides ORM features.
- LINQ to XML supports XML, with a new XML API (System.XML.Linq) that is less formal and easier to use.
- LINQ to Objects supports working with objects in memory. This is often overlooked but is very powerful, and can replace foreach loops and selections with much more succinct code.
You can return results as collections of anonymous classes. There are two styles/syntaxes for writing LINQ queries, Method Syntax and Query Syntax.
Method Syntax
(Very like SQL, just with the select statement at the end of the expression)var results = from x in staff where x.Grade = "Manager"
select new {x.Name, x.PhoneNumber}
Query Syntax
(Uses a lambda expression - input parameter(s) to an anonymous method that returns a result).
var results = staff.Where(x=>x.Grade=="Manager");
LINQ Query Operators
LINQ contains some familiar and some new (but very useful) operators:orderby
This is the same as the SQL order by clause.var doubleQuery = from method in typeof(double).GetMethods()
orderby method.Name
group method by method.Name into groups
select new { MethodName = groups.Key, NumberOfOverLoads = groups.Count() };
foreach (var item in doubleQuery)
{
Console.WriteLine(item);
}
Console.ReadLine();
group
Same as the SQL group by clause. (See orderby example, above).any
Returns true if a collection has any members.var largeList = Enumerable.Range(1,20);
var largeListEmpty = largeList.Any();
Console.WriteLine("largeList contains items? " + largeListEmpty);
contains
Returns true if a collection contains the item(s) provided in the statementConsole.WriteLine("largeList contains 7? " + largeList.Contains(7));
Console.WriteLine("largeList contains 27? " + largeList.Contains(27));
take
Takes (copies) the first n items out of the collection.var largeList = Enumerable.Range(1,20);
var smallList = largeList.Take(5).Select(x => x * 10);
foreach (var item in smallList)
{
Console.WriteLine(item);
}
foreach (var item in largeList)
{
Console.WriteLine(item);
} //largeList is unchanged as the items were copied out.
Take can be a useful way of limiting your result set.
zip
Zips together two collections (presumably they need to have a matching number of items).string[] shortMonth = { "Jan", "Feb", "Mar", "Apr", "May" };
string[] longMonth = { "January", "February", "March", "April", "May" };
var monthMapping = shortMonth.Zip(longMonth, (sMonth, lMonth) => sMonth + ": " + lMonth);
foreach (var m in monthMapping)
{
Console.WriteLine(m);
}
Console.ReadLine();
Deferred Execution
LINQ query expressions usually do not execute until we access the result, i.e. they are lazy operators. (Certain LINQ operators such as count are greedy and execute immediately). Thus you can build up queries as user input changes, and only execute it once, when needed. In the order by example, above, the LINQ query only executes when the foreach loop calls it. It is defined first but execution is deferred until needed. This is not unlike deploying a stored procedure in a database that only executes when called.
Summary
LINQ allows you to query any collection using one standard APILINQ standard operators work against IEnumerable<T>
It has many useful operators
It has a powerful chaining syntax to combine operators together powerfully.
No comments:
Post a Comment