2. INDEX
Introduction to LINQ
Why LINQ?
Language features supporting the LINQ project
Getting started with standard query operators
LINQ to Objects
Beyond basic in-memory queries
Getting started with LINQ to SQL
Peeking under the covers of LINQ to SQL
Introducing LINQ to XML
3. INTRODUCTION TO LINQ
Linq is short for Language Integrated Query.
We use the term language-integrated query to indicate
that query is an integrated feature of the developer's
primary programming languages (for example, Visual C#,
Visual Basic).
Component of .NET Framework 3.5
It is a set of methods that are defined by the
Enumerable and Queryable classes.
4. LANGUAGE INTEGRATED QUERY (LINQ)
VB C# Others…
.NET Language-Integrated Query
LINQ enabled data sources
LINQ enabled ADO.NET
LINQ
LINQ LINQ LINQ LINQ
To Objects
To DataSets To SQL To Entities To XML
<book>
<title/>
<author/>
<price/>
</book>
Objects Relational XML
5. QUERY WITHOUT LINQ
Objects using loops and conditions
foreach(Customer c in customers)
if (c.Region == "UK") ...
Databases using SQL
SELECT * FROM Customers WHERE Region='UK‘
XML using XPath/XQuery
//Customers/Customer[@Region='UK']
6. ADO WITHOUT LINQ
SqlConnection c = new SqlConnection(…);
c.Open();
SqlCommand cmd = new SqlCommand(
@”SELECT c.Name, c.Phone Query in
FROM Customers c quotes
WHERE c.City = @p0”);
Arguments loosely
cmd.Parameters[“@po”] = “London”;
bound
DataReader dr = c.Execute(cmd);
While(dr.Read()){
Results loosely
string name = r.GetString(0); bound
string phone = r.GetString(1);
Datetime date = r.GetDateTime(2);
} Compiler cannot
help catch
r.Close(); mistakes
7. LIMITATIONS
o Several steps and verbose code are required.
o Database queries bypass all kinds of compile-time checks.
o The SQL we write for a given DBMS is likely to fail on a
different one.
8. ADVANTAGES OF USING LINQ
Works with any data source.
Compile-time syntax checking, and debugging support.
IntelliSense, Design time support.
Same basic syntax for different types of data sources.
Providing designer tools that create object-relational
mappings.
9. THE SYNTAX
Starts with
from
Zero or more from,
join, let, where, or
from id in source orderby
{ from id in source |
join id in source on expr equals expr [ into id ] |
let id = expr |
Ends with
where condition | select or group
by
orderby ordering, ordering, … }
select expr | group expr by key
[ into id query ]
Optional into
continuation
11. LANGUAGE FEATURES
SUPPORTING THE LINQ PROJECT
Lambda expressions
Extension methods
Initialization of objects and collections in expression context
Local types inference
Anonymous types
Lazy evaluation
+Query Expressions
= LINQ
12. LAMBDA EXPRESSIONS
Express the implementation of a method and the
instantiation of a delegate from that method; they have the
form:
c => c + 1
which means a function with an argument, that returns the
value of the argument incremented by one
The parameters of a lambda expression can be explicitly or
implicitly typed.
13. Examples of lambda expressions
x => x + 1 // Implicitly typed, expression body
x => { return x + 1; } // Implicitly typed, statement body
(int x) => x + 1 // Explicitly typed, expression body
(int x) => { return x + 1; } // Explicitly typed, statement body
(x, y) => x * y // Multiple parameters
() => Console.WriteLine() // No parameters
A lambda expression is a value, that does not have a type but can be
implicitly converted to a compatible delegate type
delegate R Func<A,R>(A arg);
Func<int,int> f1 = x => x + 1; // Ok
Func<int,double> f2 = x => x + 1; // Ok
Func<double,int> f3 = x => x + 1; // Error – double cannot be
//implicitly converted to int
14. EXTENSION METHODS
Extend classes that you could not modify.
They are defined as static methods of other classes that
take at least one parameter, and the first parameter has
the type of the class it extends, but preceded by the
keyword this
15. EXTENSION METHODS (C#)
Extension
method
namespace MyStuff
{
public static class Extensions
{
public static string Concatenate(this IEnumerable<string>
strings,
string separator) {…}
}
}
Brings extensions into
scope
using MyStuff;
string[] names = new string[] { "Jenny", "Daniel",
"Rita" }; obj.Foo(x, y)
string s = names.Concatenate(", ");
XXX.Foo(obj, x, y)
IntelliSense!
16. Example of Extension Method:
public static int VowelCount(this String source)
{
int count = 0;
List<char> vowels = new List<char>() { 'a', 'e', 'i', 'o', 'u', 'A‘,'E', 'I', 'O', 'U' };
foreach (char c in source)
{
if (vowels.Contains(c))
count++;
}
return count;
}
string name = “extension”;
int count = name.VowelCount();
17. INITIALIZATION OF OBJECTS AND
COLLECTIONS IN EXPRESSION
CONTEXT
Object initializers let you assign values to any accessible fields or
properties of an object at creation time without having to explicitly
invoke a constructor.
Example:
private class Cat
{
// Auto-implemented properties.
public int Age { get; set; }
public string Name { get; set; }
}
Cat cat = new Cat { Age = 10, Name = "Fluffy" };
18.
19. Collection Initializers
Collection initializers let you specify one or more element intializers
when you initialize a collection class that implements IEnumerable.
Two simple collection intializers
List<int> digits = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
List<int> digits2 = new List<int> { 0 + 1, 12 % 3, MakeInt() };
The following collection initializer uses object initializers to initialize
objects of the Cat class
List<Cat> cats = new List<Cat>
{
new Cat(){ Name = "Sylvester", Age=8 },
new Cat(){ Name = "Whiskers", Age=2 },
new Cat(){ Name = "Sasha", Age=14 }
};
20. Anonymous Types, Implicitly Typed variables
An anonymous type has no name and is generated by the compiler
based on the initialization of the object being instantiated.
var results = from employee in employees
join contact in contacts
on employee.Id equals contact.Id
select new {
employee.FirstName, employee.LastName, contact.City };
the part at “select new”, it’s not using any class name there to
initialize, but it’s there and it’s anonymous
That is the purpose of the var keyword. It infers the type of the
object based on the data type with which it has been intialized
21. LOCAL VARIABLE TYPE INFERENCE (C#)
int i = 666;
string s = "Goodbye";
double d = 3.14;
int[] numbers = new int[] {1, 2, 3};
Dictionary<int,Order> orders = new
Dictionary<int,Order>();
var i = 666;
var s = "Goodbye";
var d = 3.14;
var numbers = new int[] {1, 2, 3};
var orders = new Dictionary<int,Order>();
“The type on the
right hand side”
22. • Variable type inferred from initialiser
Integer
String
var x = 666
var s = “Bye" Double
var d = 3.14
var numbers = new Integer() {1, 2, 3}
var orders = new Dictionary(Of Integer, Order)()
23. LAZY EVALUATION
LINQ follows a lazy evaluation model
Queries execute not when constructed, but when enumerated.
This means you can build up a query in as many steps as you like, and it
won't actually hit the server until you eventually start consuming the
results.
var query = db.Customers.Where (c => c.Name.StartsWith ("A")); query =
query.Where (c => c.Purchases.Count() >= 2);
var result = query.Select (c => c.Name);
foreach (string name in result) //Only now is the query executed!
Console.WriteLine (name);
24. C# 3.5 LANGUAGE INNOVATIONS
var contacts = Query
expressions
from c in customers
where c.City == "Hove"
Local variable select new { c.Name, c.Phone };
type inference
Lambda
expressions
var contacts =
customers
.Where(c => c.City == "Hove")
.Select(c => new { c.Name, c.Phone });
Extension
methods Anonymous Object
types initializers
26. GETTING STARTED WITH
STANDARD QUERY OPERATORS
LINQ Query operators are an extension to the .NET Framework
Class Library.
These are a set of extension methods to perform operations in the
context of LINQ queries.
These operators are at the heart of the LINQ foundation and they
are the real elements that make LINQ possible.
28. THE FOLLOWING IS THE LIST OF STANDARD QUERY
OPERATORS ALONG WITH THEIR CATEGORY:
29.
30. LINQ EXAMPLE - QUERYING AN ARRAY
//Create an array of integers
int[] myarray = new int[] { 49, 28, 20, 15, 25,
23, 24, 10, 7, 34 };
//Create a query for odd numbers
var oddNumbers = from i in myarray where i % 2 == 1 select i;
//Compose the original query to create a query for odd numbers
var sorted = from i in oddNumbers orderby i descending select i;
//Display the results of the query
foreach (int i in oddNumbers)
Console.WriteLine(i);
31. Query translates to method invocation.
Where, Join, OrderBy, Select, GroupBy, …
from c in customers
where c.City == "Hove"
select new { c.Name, c.Phone };
customers
.Where(c => c.City == "Hove")
.Select(c => new { c.Name, c.Phone });
35. Querying non-generic collection
Trying to query an ArrayList using LINQ to Objects directly fails
ArrayList books = GetArrayList();
var query = from book in books where book.PageCount > 150
select new { book.Title, book.Publisher.Name };
Nongeneric collections aren’t a big problem with LINQ once you know the trick.
The trick is to use the Cast operator
Querying an ArrayList is possible thanks to the Cast query operator
ArrayList books = GetArrayList();
var query = from book in books.Cast<Book>()
where book.PageCount > 150
select new { book.Title, book.Publisher.Name };
dataGridView.DataSource = query.ToList();
36. Grouping by multiple criteria
var query1 = from book in SampleData.Books
group book by book.Publisher, book.Subject;
var query2 = from book in SampleData.Books
group book by book.Publisher
group book by book.Subject;
The trick is to use an anonymous type to specify the members on which to perform the
grouping.
var query = from book in SampleData.Books
group book by new { book.Publisher, book.Subject };
37. LINQ ARCHITECTURE
var query = from c in customers where c.City == "Hove" select c.Name;
var query = customers.Where(c => c.City == "Hove").Select(c => c.Name);
Source implements Source implements
IEnumerable<T> IQueryable<T>
System.Linq.Enumerable System.Linq.Queryable
Delegate based Expression tree based
Objects SQL DataSets Others…
39. WHAT IS LINQ TO SQL?
LINQ to SQL is an O/RM (object relational mapping) implementation
that ships in the .NET Framework. Which allows you to model a
relational database using .NET classes.
You can then query the database using LINQ, as well as update/ insert/
delete data from it.
LINQ to SQL fully supports transactions, views, and stored procedures.
It also provides an easy way to integrate data validation and business
logic rules into your data model.
40. THE DATACONTEXT, WHAT IS IT?
DataContext will be created for each LinqToSQL-File we
add to our solution.
The DataContext is the main object through which we
will communicate with our database.
The properties of the DataContext class are the tables
and stored procedures in the database we
modelled/created.
41. DLINQ RUNTIME SUPPORT
from c in db.Customers db.Customers.Add(c1);
where c.City == "London"
select c.CompanyName
Application c2.City = “Seattle";
db.Customers.Remove(c3);
Enumerate Objects SubmitChanges()
LINQ to
SQL
SQL Query Rows DML
or SProc or SProcs
SELECT CompanyName INSERT INTO Customer …
FROM Customer UPDATE Customer …
WHERE City = 'London' DELETE FROM Customer …
45. LINQ TO XML
Large Improvement Over Existing Model
Supports:
Creating XML
Loading & querying XML
Modifying & saving XML
Streaming, Schema, Annotations, Events
46. LINQ TO XML
New XML API implemented in v3.5 assembly
System.Xml.Linq.dll
Namespaces
System.Xml.Linq
System.Xml.Schema
System.Xml.Xpath
Can be used independently of LINQ
47. KEY CLASSES IN SYSTEM.XML.LINQ
System.Xml.Linq is a “DOM like” API
Manipulates an XML tree in memory
Naturally work with both XML documents and fragments
The two key classes in System.Xml.Linq
48. LOADING XML CONTENT
Loading Xml is performed with;
XElement.Load
XDocument.Load
Both support loading from
URI, XmlReader, TextReader
49. MODIFYING XML
XML tree exposed by XElement is modifiable
Modifications through methods such as:
XElement.Add()
XElement.Remove()
XElement.ReplaceWith()
Modified tree can be persisted via
XElement.Save(), XDocument.Save()
Both supporting filename, TextWriter, XmlWriter.
50. CREATING AN XML DOCUMENT
XNamespace ns = "http://example.books.com";
XDocument books = new XDocument(
new XElement(ns + "bookstore",
new XElement(ns + "book",
new XAttribute("ISBN", isbn),
new XElement(ns + "title", "ASP.NET Book"),
new XElement(ns + "author",
new XElement(ns + "first-name", a.FirstName),
new XElement(ns + "last-name", a.LastName)
)
)
)
);
books.Save(@"C:Books.xml");
51. …MEANWHILE IN C#
No XML Literals, But There’s
Something to Close the Gap
“Paste XML as XElement” Add-in
Add XML to Clipboard
Edit -> Past XML as XElement
Included in VS2008 Samples
Help -> Samples