Introduction to LINQ
Paul Litwin
Deep Training
paull@deeptraining.com
1
Agenda
What is LINQ?
Language Features Behind LINQ
LINQ Basics
LINQ to Objects
LINQ to SQL
Other LINQ providers

2
Paul Litwin
Developer
Focus: ASP.NET, ASP, VB, C#, SQL Server, …
MCSD
Microsoft MVP
Programming Manger with
Fred Hutchinson Cancer Research Center (Seattle)

Co-Founder and Senior Trainer
Deep Training
www.deeptraining.com

Conference Chair/Speaker
Chair, Microsoft ASP.NET Connections
Member INETA Speakers Bureau

Author
Author/co-author of a dozen books, including…
ASP.NET for Developers
Access Cookbook, 2nd edition
Access 2002 Desktop/Enterprise Dev Handbook
AppDev SQL Server 2005 Reporting Services Course

3
This Talk Brought to You By…
INETA
International .NET Users Association
Speaker Bureau

4
What is LINQ?
LINQ == Language Integrated Query
Additions to .NET languages that enable
language-based querying
LINQ Providers
LINQ to Objects – in memory-collections
LINQ to SQL – SQL Server databases
LINQ to XML – XML documents
LINQ to DataSets – data in a ADO.NET DataSet
LINQ to Entities – works with ADO.NET Entity
Framework
…

5
Language Features Behind LINQ
Automatic Properties
Object and Collection Initializers
Inferred and Anonymous Types
Extension Methods
Lambda Expressions

6
Automatic Properties – C# Only
Quick way to define property Not really
necessary for LINQ but nice
replace this

with this

private string _firstName;
private string _firstName;

public string firstName { get; set; }
public string firstName { get; set; }

public string firstName
public string firstName
{
{
get { return _firstName; }
get { return _firstName; }
set { _firstName = value; }
set { _firstName = value; }
}
}

7
Object Initializers – C#
Quick way to create an instance and set a
bunch of properties
replace this
Cust20 cust20 = new Cust20();
Cust20 cust20 = new Cust20();
cust20.firstName = "Groucho";
cust20.firstName = "Groucho";
cust20.lastName = "Marx";
cust20.lastName = "Marx";
cust20.birthDate = new DateTime(1890, 10, 2);
cust20.birthDate = new DateTime(1890, 10, 2);

with this
Cust35 cust35 = new Cust35 { firstName = "Jim",
Cust35 cust35 = new Cust35 { firstName = "Jim",
lastName = "Gaffigan", birthDate = new DateTime(1966, 7, 7) };
lastName = "Gaffigan", birthDate = new DateTime(1966, 7, 7) };
8
Object Initializers – VB
Quick way to create an instance and set a
bunch of properties
replace this
Dim cust20 As New Cust20()
Dim cust20 As New Cust20()
cust20.firstName = "Groucho"
cust20.firstName = "Groucho"
cust20.lastName = "Marx"
cust20.lastName = "Marx"
cust20.birthDate = New DateTime(1890, 10, 2)
cust20.birthDate = New DateTime(1890, 10, 2)

with this
Dim cust20 As New Cust20() With {.firstName = "Jim", _
Dim cust20 As New Cust20() With {.firstName = "Jim", _
.lastName = "Gaffigan", .birthDate = New DateTime(1966, 7, 7)}
.lastName = "Gaffigan", .birthDate = New DateTime(1966, 7, 7)}
9
Collection Initializers – C# Only
replace this
List<Cust20> pcTitans20 = new List<Cust20>();
List<Cust20> pcTitans20 = new List<Cust20>();
Cust20 steveJobs = new Cust20();
Cust20 steveJobs = new Cust20();
steveJobs.firstName = "Steve";
steveJobs.firstName = "Steve";
steveJobs.lastName = "Jobs";
steveJobs.lastName = "Jobs";
steveJobs.birthDate = new DateTime(1955, 2, 24);
steveJobs.birthDate = new DateTime(1955, 2, 24);
pcTitans20.Add(steveJobs);
pcTitans20.Add(steveJobs);
…
…

with this
List<Cust20> pcTitans35 = new List<Cust35>
List<Cust20> pcTitans35 = new List<Cust35>
{
{
new Cust35{firstName="Steve",lastName="Jobs",
new Cust35{firstName="Steve",lastName="Jobs",
birthDate=new DateTime(1955,2,24)},
birthDate=new DateTime(1955,2,24)},
…
…
}
}

10
Type Inference
Have compiler infer type from usage
C#

var serialNumber1 = 123456;
var serialNumber2 = "789";

// inferred as int
// inferred as string

VB

Dim serialNumber1 = 123456
Dim serialNumber2 = "789"

' inferred as int
' inferred as string

11
Anonymous Types
Allow you create an instance of an unnamed (i.e., anonymous) class that is
defined in line
C#
var myHouse = new {color = "green", address = "100 Elm"}

VB
Dim myHouse = New With {.color = "green", _
.address = "100 Elm"}

12
Extension Methods – C#
Allow you to add a custom method to an
existing type
public static class ScottGuExtensions
{
public static bool IsValidEmailAddress (this string s)
{
Regex regex = new
Regex(@"^[w-.]+@([w-]+.)+[w-]{2,4}$");
return regex.IsMatch(s);
}
}
13
Extension Methods – VB
Allow you to add a custom method to an
existing type
Imports System.Runtime.CompilerServices
Imports System.Text.RegularExpressions
Public Module ScottGuExtensions
Public
ScottGuExtensions
<Extension()> _
Public Function IsValidEmailAddess(ByVal s As String) _
As Boolean
Dim regex As Regex = _
As
New Regex("^[w-.]+@([w-]+.)+[w-]{2,4}$")
Return regex.IsMatch(s)
End Function
End Module

14
Basic LINQ Examples
Comedians = new List<String> { "Groucho Marx", "Eric Idle", … }
var results = from c in Comedians
where c.Contains("Marx")
select c;
var results = from c in Comedians
orderby c
select c;

LINQ2Objects.aspx – C#
LINQ2ObjectsVB.aspx – VB
15
Query Basics – C#
Query expression consists of set of clauses written
in a declarative syntax similar to SQL or XQuery
Query must
begin with from clause, and
end with select or group clause

Between 1st from clause and last select/group
clause, it can contain one or more of following
clauses
where
orderby
join
let
from
into

16
Query Basics – VB
Query expression consists of set of clauses written
in a declarative syntax similar to SQL or XQuery
Query must
begin with From or Aggregate clause

After From/Aggregate clause, you may include any
of following clauses
Select
Where
Order By
Join
Group By
Aggregate
Let

Distinct
Take
Take While
Skip
Skip While
Into
17
Contrasting Query Keywords
C# LINQ

VB LINQ

ANSI SQL

from

From

FROM

select

Select

SELECT

where

Where

WHERE

orderby

Order By

ORDER BY

join

Join

JOIN

group

Group By

GROUP BY

Distinct()

Distinct

DISTINCT

into

Into

INTO

let

Let

AS

Count(), Sum(),…

Aggregate

COUNT, SUM,… w/ no group

Skip()
SkipWhile()

Skip
Skip While

n/a

Take()
TakeWhile()

Take
Take While

n/a

18
LINQ Basics
There are two ways to write LINQ queries
Query syntax
The previous examples used this syntax

Method syntax
This syntax uses Lambda expressions

19
Anonymous Methods Review
C# 2.0 introduced anonymous methods
C# 1.0
btn.Click += new EventHandler(btn_Click):
btn.Click += new EventHandler(btn_Click):
void btn_Click(object sender, EventArgs e)
void btn_Click(object sender, EventArgs e)
{
{
lblResult.txt = "Hello world";
lblResult.txt = "Hello world";
}
}

C 2.0
btn.Click += delegate(object sender, EventArgs e)
btn.Click += delegate(object sender, EventArgs e)
{
{
lblResult.Text = "Hello World";
lblResult.Text = "Hello World";
}
}
20
Lambda Expressions
Lambda expression take the C# 2.0
anonymous method one step further
C 2.0
btn.Click += delegate(object sender, EventArgs e)
btn.Click += delegate(object sender, EventArgs e)
{
{
lblResult.Text = "Hello!";
lblResult.Text = "Hello!";
}
}

C 3.0
btn.Click += (object sender, EventArgs e) => lblResult.Text = "Hello!";
btn.Click += (object sender, EventArgs e) => lblResult.Text = "Hello!";

-orbtn.Click += (sender, e) => lblResult.Text = "Hello!";
btn.Click += (sender, e) => lblResult.Text = "Hello!";
21
Lambda Expressions
=> goes into
separates parameters from method body
can drop parentheses when there is only
one parameter

22
LINQ – C#
Equivalent LINQ queries
query syntax
var results = from c in Comedians
where c.Contains("Marx")
select c;

method (lambda expression) syntax
var results = Comedians.Where(c => c.Contains("Marx"));

23
LINQ – VB
Equivalent LINQ queries
query syntax
Dim results = From c In Comedians _
Where (c.Contains("Marx")) _
Select c

method (lambda expression) syntax
Dim results = Comedians.Where(Function(c) c.Contains("Marx"))

24
LINQ – Hybrid Syntax
You can also use a hybrid of query and
method syntax
often this is necessary because using query
syntax alone is not expressive enough,
especially when using C#
var results = (from c in Comedians
select c).Count();

25
LINQ to Objects
If an object supports either IEnumerable
or IEnumerable<T> interface, LINQ to
Objects provider enables you to query it
Array, ArrayList, collections, generic
collections, …
System.Linq namespace
All examples shown so far have used
LINQ to Objects
26
LINQ to SQL
System.Data.Linq namespace
Works with SQL Server 2000/2005
Requires entity classes which you can
build using the Object Relational Designer
(ORD)
Entity Framework will let you use LINQ
with other databases using E-R data
models
27
Using ORD (1 of 3)
Add to your App_Code folder

28
Using ORD (2 of 3)

29
Using ORD (3 of 3)
Generated designer.cs file

30
Binding to a LINQ Query
Once the ORD created, you can
reference its DataContext
NorthwindDataContext db = new
NorthwindDataContext();
var results = from cust in db.Customers
where cust.Country == "USA"
orderby cust.CompanyName
select cust;
gvCustomers.DataSource = results;
gvCustomers.DataBind();

Example: CustomersGrid1.aspx

31
Alternately…
You can use LINQ data source

Example: CustomersGrid2.aspx
32
LINQ Tools
LINQPad
free tool for testing LINQ queries
from Joseph Albahari
http://www.linqpad.net/

LINQ Debug Visualizer
free download from Microsoft
http://www.scottgu.com/blogposts/linqquery/
sqlserverqueryvisualizer.zip
33
Selecting Fields
All fields (CustomersGrid1.aspx)
var results = from cust in db.Customers
select cust;
Subset of fields –notice use of "new"
to create anonymous type (CustomersGrid3.aspx)
var results = from cust in db.Customers
select new
{
cust.CompanyName,
cust.ContactName,
cust.City
};
34
Filtering Data
var results = from cust in db.Customers
where (cust.Country == "USA" &&
(cust.CompanyName.ToLower().StartsWith("t") ||
cust.CustomerID.ToLower().StartsWith("t")))
orderby cust.CompanyName
select cust;

Filter1.aspx

35
Using ORD Associations
ORD automatically adds associations for
database relationships
var results = from c in db.Customers
where c.Country == "USA"
select new
{
c.CompanyName,
c.City,
TotalOrders = c.Orders.Count,
LastOrder = c.Orders.Max(o => o.OrderDate)
};

Association1.aspx
36
Associations
You can always get to 1st order
associations
Getting to 2nd and 3rd order associations
requires you to compose your query so
that you traverse 1—m relationships from
the many side to the one side
Contrast
Association1.aspx, and
Association2.aspx
37
Ordering Data
// ascending is default order
var results = from cust in db.Customers
orderby cust.Country,
cust.Orders.Count descending
select new
{
cust.Country,
cust.City,
cust.CompanyName,
Orders = cust.Orders.Count
};

Order1.aspx
38
Joining Tables
var results = from order in db.Orders
join detail in db.Order_Details
on order.OrderID equals detail.OrderID
join product in db.Products
on detail.ProductID equals product.ProductID
join customer in db.Customers
on order.CustomerID equals customer.CustomerID
select new
{
customer.CompanyName,
order.OrderDate,
product.ProductName,
detail.UnitPrice,
Cost = detail.UnitPrice * detail.Quantity
};

Join1.aspx

39
Grouping Data
from d in db.Order_Details
from d in db.Order_Details
group new
group new
{
{
order = d.Order,
order = d.Order,
detail = d,
detail = d,
customer = d.Order.Customer
customer = d.Order.Customer
} by d.Order.Customer.CompanyName into grpQuery
} by d.Order.Customer.CompanyName into grpQuery
select new
select new
{
{
Company = grpQuery.Key,
Company = grpQuery.Key,
Purchases = grpQuery.Count(),
Purchases = grpQuery.Count(),
FirstOrder = grpQuery.Min(g => g.order.OrderDate),
FirstOrder = grpQuery.Min(g => g.order.OrderDate),
LastOrder = grpQuery.Max(g => g.order.OrderDate),
LastOrder = grpQuery.Max(g => g.order.OrderDate),
TotalCost = grpQuery.Sum(g => g.detail.Quantity * g.detail.UnitPrice)
TotalCost = grpQuery.Sum(g => g.detail.Quantity * g.detail.UnitPrice)
};
};

Group1.aspx
40
Calling Stored Procedure
Drag sproc from Server Explorer to data
model
Call sproc as method of data context
Example: CustomersFromSproc.aspx
var customersByCountry =
db.procCustomerSelectByCountry(ddlCountry.SelectedValue);
gv.DataSource = customersByCountry;
gv.DataBind();

41
Updating Data
Can update, of course, using sprocs
You can also use LinqDataSource control
Example: UpdateCategories1.aspx

You can also use an ObjectDataSource
control against a Data Access Layer (DAL)
Example: UpdateCategories2.aspx
see excerpt in later slide

This example also illustrates use of LINQ for
SQL Server data paging
42
Using LinqDataSource Control

43
Updating Data Example
public void Update(CategoryDAL cat2Update)
{
var cat = (from c in db.Categories
where (c.CategoryID == cat2Update.CategoryId)
select c).Single();
cat.CategoryName = cat2Update.CategoryName;
cat.Description = cat2Update.Description;
db.SubmitChanges();
}

44
SQL Server Data Paging
public List<CategoryDAL> Select(int startRowIndex, int maximumRows)
public List<CategoryDAL> Select(int startRowIndex, int maximumRows)
{
{
var cat = (from category in db.Categories
var cat = (from category in db.Categories
orderby category.CategoryID
orderby category.CategoryID
select new
select new
{
{
category.CategoryID,
category.CategoryID,
category.CategoryName,
category.CategoryName,
category.Description
category.Description
}).Skip(startRowIndex).Take(maximumRows);
}).Skip(startRowIndex).Take(maximumRows);
List<CategoryDAL> catList = new List<CategoryDAL>();
List<CategoryDAL> catList = new List<CategoryDAL>();
foreach (var c in cat)
foreach (var c in cat)
{
{
CategoryDAL cd = new CategoryDAL();
CategoryDAL cd = new CategoryDAL();
cd.CategoryId = c.CategoryID;
cd.CategoryId = c.CategoryID;
cd.CategoryName = c.CategoryName;
cd.CategoryName = c.CategoryName;
cd.Description = c.Description;
cd.Description = c.Description;
catList.Add(cd);
catList.Add(cd);
}
}
return catList;
return catList;
}
}

45
Other LINQ Providers
LINQ to XML
LINQ to DataSets (aka LINQ to ADO.NET)
LINQ to Entities

46
LINQ to DataSets (aka LINQ to ADO.NET)
Grab data from ADO.NET and put it into a
DataSet, DataTable
Use LINQ to shape the data

47
LINQ to DataSet Example
Example: LINQ2Dataset.aspx
cnx = new SqlConnection(strCnx);
cnx = new SqlConnection(strCnx);
sda = new SqlDataAdapter("procCustomersSelect", cnx);
sda = new SqlDataAdapter("procCustomersSelect", cnx);
sda.SelectCommand.CommandType = CommandType.StoredProcedure;
sda.SelectCommand.CommandType = CommandType.StoredProcedure;
dt = new DataTable();
dt = new DataTable();
sda.Fill(dt);
sda.Fill(dt);
var cust = from c in dt.AsEnumerable()
var cust = from c in dt.AsEnumerable()
orderby c.Field<string>("ContactName")
orderby c.Field<string>("ContactName")
select new
select new
{
{
Contact = c.Field<string>("ContactName"),
Contact = c.Field<string>("ContactName"),
Company = c.Field<string>("CompanyName"),
Company = c.Field<string>("CompanyName"),
Location = c.Field<string>("City") + ", " +
Location = c.Field<string>("City") + ", " +
c.Field<string>("Country")
c.Field<string>("Country")
};
};
48
Other LINQ Providers
LINQ to Entities
Takes O/RM much further than LINQ to SQL
Part of Visual Studio SP 1

49
Discussion Points
When are LINQ's strengths?
What are its weaknesses?
Is LINQ the future of data access in .NET?
Or is the more "classic" N-tier, ADO.NET,
stored procedures approach make more
sense in many scenarios?

50
LINQ Resources
LINQPad
http://www.linqpad.net/

LINQ Debug Visualizer
http://www.scottgu.com/blogposts/linqquery/
sqlserverqueryvisualizer.zip

Scott Guthrie's Blog
http://weblogs.asp.net/scottgu/

51
Thank You!
Slides and samples can be downloaded
from
www.deeptraining.com/litwin

52

More Related Content

DOCX
Virtual function
PDF
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
PDF
Le langage rust
PDF
Swift cooking course making a cake ... pattern
PPTX
C# for C++ programmers
PDF
Java Keeps Throttling Up!
PDF
C# / Java Language Comparison
ODP
Ppt of c++ vs c#
Virtual function
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
Le langage rust
Swift cooking course making a cake ... pattern
C# for C++ programmers
Java Keeps Throttling Up!
C# / Java Language Comparison
Ppt of c++ vs c#

What's hot (20)

PPTX
07. Virtual Functions
PDF
Solid C++ by Example
PDF
C++ questions And Answer
PPTX
C# for C++ Programmers
PPS
C++ Language
PPTX
Summary of C++17 features
PPTX
P/Invoke - Interoperability of C++ and C#
PDF
Modern c++ (C++ 11/14)
PDF
C++11 concurrency
PPT
Gentle introduction to modern C++
PPT
Cocoa for Web Developers
ODP
OOP in C - Before GObject (Chinese Version)
PDF
C++ idioms by example (Nov 2008)
PPTX
Polymorphism
PDF
Writing Parsers and Compilers with PLY
PDF
Modern C++
PPTX
C++ Presentation
PPT
Constructor,destructors cpp
07. Virtual Functions
Solid C++ by Example
C++ questions And Answer
C# for C++ Programmers
C++ Language
Summary of C++17 features
P/Invoke - Interoperability of C++ and C#
Modern c++ (C++ 11/14)
C++11 concurrency
Gentle introduction to modern C++
Cocoa for Web Developers
OOP in C - Before GObject (Chinese Version)
C++ idioms by example (Nov 2008)
Polymorphism
Writing Parsers and Compilers with PLY
Modern C++
C++ Presentation
Constructor,destructors cpp
Ad

Viewers also liked (6)

DOCX
Differences
PDF
Html5 tutorial
PPTX
عرض تقديميHgh1
PPTX
Pinterst
PDF
linq with Exampls
PPTX
Brown Dog Feltboard
Differences
Html5 tutorial
عرض تقديميHgh1
Pinterst
linq with Exampls
Brown Dog Feltboard
Ad

Similar to Litwin linq (20)

PPTX
Basic vbscript for qtp
PPTX
Share pointtechies linqtosp-andsbs
PDF
7400354 vbscript-in-qtp
PPT
Visual studio 2008
PPT
Major Java 8 features
PDF
Intake 37 linq2
PDF
Property Wrappers or how Swift decided to become Java
PDF
Top 10 bugs in C++ open source projects, checked in 2016
PPTX
Lambdas puzzler - Peter Lawrey
PDF
S.M.A.R.T. Biml - Standardize, Model, Automate, Reuse and Transform (SQLSatur...
PDF
Дмитрий Верескун «Синтаксический сахар C#»
PPTX
CSharp Presentation
PDF
Adapting clean architecture in android apps
PPTX
C#.net evolution part 2
PPT
C# features
PPT
Linq intro
PPT
Understanding linq
PDF
PDF
Dr archana dhawan bajaj - csharp fundamentals slides
PPTX
What's new in C# 8.0 (beta)
Basic vbscript for qtp
Share pointtechies linqtosp-andsbs
7400354 vbscript-in-qtp
Visual studio 2008
Major Java 8 features
Intake 37 linq2
Property Wrappers or how Swift decided to become Java
Top 10 bugs in C++ open source projects, checked in 2016
Lambdas puzzler - Peter Lawrey
S.M.A.R.T. Biml - Standardize, Model, Automate, Reuse and Transform (SQLSatur...
Дмитрий Верескун «Синтаксический сахар C#»
CSharp Presentation
Adapting clean architecture in android apps
C#.net evolution part 2
C# features
Linq intro
Understanding linq
Dr archana dhawan bajaj - csharp fundamentals slides
What's new in C# 8.0 (beta)

Recently uploaded (20)

PDF
Architecture types and enterprise applications.pdf
PPTX
O2C Customer Invoices to Receipt V15A.pptx
PDF
A comparative study of natural language inference in Swahili using monolingua...
PPTX
Modernising the Digital Integration Hub
PPTX
The various Industrial Revolutions .pptx
PDF
Five Habits of High-Impact Board Members
PDF
Getting Started with Data Integration: FME Form 101
PDF
A Late Bloomer's Guide to GenAI: Ethics, Bias, and Effective Prompting - Boha...
PDF
NewMind AI Weekly Chronicles – August ’25 Week III
PPTX
Group 1 Presentation -Planning and Decision Making .pptx
PDF
Microsoft Solutions Partner Drive Digital Transformation with D365.pdf
PDF
Getting started with AI Agents and Multi-Agent Systems
PDF
DP Operators-handbook-extract for the Mautical Institute
PDF
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game
PDF
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
PDF
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
PDF
STKI Israel Market Study 2025 version august
PDF
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
PDF
A review of recent deep learning applications in wood surface defect identifi...
PDF
Taming the Chaos: How to Turn Unstructured Data into Decisions
Architecture types and enterprise applications.pdf
O2C Customer Invoices to Receipt V15A.pptx
A comparative study of natural language inference in Swahili using monolingua...
Modernising the Digital Integration Hub
The various Industrial Revolutions .pptx
Five Habits of High-Impact Board Members
Getting Started with Data Integration: FME Form 101
A Late Bloomer's Guide to GenAI: Ethics, Bias, and Effective Prompting - Boha...
NewMind AI Weekly Chronicles – August ’25 Week III
Group 1 Presentation -Planning and Decision Making .pptx
Microsoft Solutions Partner Drive Digital Transformation with D365.pdf
Getting started with AI Agents and Multi-Agent Systems
DP Operators-handbook-extract for the Mautical Institute
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
STKI Israel Market Study 2025 version august
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
A review of recent deep learning applications in wood surface defect identifi...
Taming the Chaos: How to Turn Unstructured Data into Decisions

Litwin linq

  • 2. Agenda What is LINQ? Language Features Behind LINQ LINQ Basics LINQ to Objects LINQ to SQL Other LINQ providers 2
  • 3. Paul Litwin Developer Focus: ASP.NET, ASP, VB, C#, SQL Server, … MCSD Microsoft MVP Programming Manger with Fred Hutchinson Cancer Research Center (Seattle) Co-Founder and Senior Trainer Deep Training www.deeptraining.com Conference Chair/Speaker Chair, Microsoft ASP.NET Connections Member INETA Speakers Bureau Author Author/co-author of a dozen books, including… ASP.NET for Developers Access Cookbook, 2nd edition Access 2002 Desktop/Enterprise Dev Handbook AppDev SQL Server 2005 Reporting Services Course 3
  • 4. This Talk Brought to You By… INETA International .NET Users Association Speaker Bureau 4
  • 5. What is LINQ? LINQ == Language Integrated Query Additions to .NET languages that enable language-based querying LINQ Providers LINQ to Objects – in memory-collections LINQ to SQL – SQL Server databases LINQ to XML – XML documents LINQ to DataSets – data in a ADO.NET DataSet LINQ to Entities – works with ADO.NET Entity Framework … 5
  • 6. Language Features Behind LINQ Automatic Properties Object and Collection Initializers Inferred and Anonymous Types Extension Methods Lambda Expressions 6
  • 7. Automatic Properties – C# Only Quick way to define property Not really necessary for LINQ but nice replace this with this private string _firstName; private string _firstName; public string firstName { get; set; } public string firstName { get; set; } public string firstName public string firstName { { get { return _firstName; } get { return _firstName; } set { _firstName = value; } set { _firstName = value; } } } 7
  • 8. Object Initializers – C# Quick way to create an instance and set a bunch of properties replace this Cust20 cust20 = new Cust20(); Cust20 cust20 = new Cust20(); cust20.firstName = "Groucho"; cust20.firstName = "Groucho"; cust20.lastName = "Marx"; cust20.lastName = "Marx"; cust20.birthDate = new DateTime(1890, 10, 2); cust20.birthDate = new DateTime(1890, 10, 2); with this Cust35 cust35 = new Cust35 { firstName = "Jim", Cust35 cust35 = new Cust35 { firstName = "Jim", lastName = "Gaffigan", birthDate = new DateTime(1966, 7, 7) }; lastName = "Gaffigan", birthDate = new DateTime(1966, 7, 7) }; 8
  • 9. Object Initializers – VB Quick way to create an instance and set a bunch of properties replace this Dim cust20 As New Cust20() Dim cust20 As New Cust20() cust20.firstName = "Groucho" cust20.firstName = "Groucho" cust20.lastName = "Marx" cust20.lastName = "Marx" cust20.birthDate = New DateTime(1890, 10, 2) cust20.birthDate = New DateTime(1890, 10, 2) with this Dim cust20 As New Cust20() With {.firstName = "Jim", _ Dim cust20 As New Cust20() With {.firstName = "Jim", _ .lastName = "Gaffigan", .birthDate = New DateTime(1966, 7, 7)} .lastName = "Gaffigan", .birthDate = New DateTime(1966, 7, 7)} 9
  • 10. Collection Initializers – C# Only replace this List<Cust20> pcTitans20 = new List<Cust20>(); List<Cust20> pcTitans20 = new List<Cust20>(); Cust20 steveJobs = new Cust20(); Cust20 steveJobs = new Cust20(); steveJobs.firstName = "Steve"; steveJobs.firstName = "Steve"; steveJobs.lastName = "Jobs"; steveJobs.lastName = "Jobs"; steveJobs.birthDate = new DateTime(1955, 2, 24); steveJobs.birthDate = new DateTime(1955, 2, 24); pcTitans20.Add(steveJobs); pcTitans20.Add(steveJobs); … … with this List<Cust20> pcTitans35 = new List<Cust35> List<Cust20> pcTitans35 = new List<Cust35> { { new Cust35{firstName="Steve",lastName="Jobs", new Cust35{firstName="Steve",lastName="Jobs", birthDate=new DateTime(1955,2,24)}, birthDate=new DateTime(1955,2,24)}, … … } } 10
  • 11. Type Inference Have compiler infer type from usage C# var serialNumber1 = 123456; var serialNumber2 = "789"; // inferred as int // inferred as string VB Dim serialNumber1 = 123456 Dim serialNumber2 = "789" ' inferred as int ' inferred as string 11
  • 12. Anonymous Types Allow you create an instance of an unnamed (i.e., anonymous) class that is defined in line C# var myHouse = new {color = "green", address = "100 Elm"} VB Dim myHouse = New With {.color = "green", _ .address = "100 Elm"} 12
  • 13. Extension Methods – C# Allow you to add a custom method to an existing type public static class ScottGuExtensions { public static bool IsValidEmailAddress (this string s) { Regex regex = new Regex(@"^[w-.]+@([w-]+.)+[w-]{2,4}$"); return regex.IsMatch(s); } } 13
  • 14. Extension Methods – VB Allow you to add a custom method to an existing type Imports System.Runtime.CompilerServices Imports System.Text.RegularExpressions Public Module ScottGuExtensions Public ScottGuExtensions <Extension()> _ Public Function IsValidEmailAddess(ByVal s As String) _ As Boolean Dim regex As Regex = _ As New Regex("^[w-.]+@([w-]+.)+[w-]{2,4}$") Return regex.IsMatch(s) End Function End Module 14
  • 15. Basic LINQ Examples Comedians = new List<String> { "Groucho Marx", "Eric Idle", … } var results = from c in Comedians where c.Contains("Marx") select c; var results = from c in Comedians orderby c select c; LINQ2Objects.aspx – C# LINQ2ObjectsVB.aspx – VB 15
  • 16. Query Basics – C# Query expression consists of set of clauses written in a declarative syntax similar to SQL or XQuery Query must begin with from clause, and end with select or group clause Between 1st from clause and last select/group clause, it can contain one or more of following clauses where orderby join let from into 16
  • 17. Query Basics – VB Query expression consists of set of clauses written in a declarative syntax similar to SQL or XQuery Query must begin with From or Aggregate clause After From/Aggregate clause, you may include any of following clauses Select Where Order By Join Group By Aggregate Let Distinct Take Take While Skip Skip While Into 17
  • 18. Contrasting Query Keywords C# LINQ VB LINQ ANSI SQL from From FROM select Select SELECT where Where WHERE orderby Order By ORDER BY join Join JOIN group Group By GROUP BY Distinct() Distinct DISTINCT into Into INTO let Let AS Count(), Sum(),… Aggregate COUNT, SUM,… w/ no group Skip() SkipWhile() Skip Skip While n/a Take() TakeWhile() Take Take While n/a 18
  • 19. LINQ Basics There are two ways to write LINQ queries Query syntax The previous examples used this syntax Method syntax This syntax uses Lambda expressions 19
  • 20. Anonymous Methods Review C# 2.0 introduced anonymous methods C# 1.0 btn.Click += new EventHandler(btn_Click): btn.Click += new EventHandler(btn_Click): void btn_Click(object sender, EventArgs e) void btn_Click(object sender, EventArgs e) { { lblResult.txt = "Hello world"; lblResult.txt = "Hello world"; } } C 2.0 btn.Click += delegate(object sender, EventArgs e) btn.Click += delegate(object sender, EventArgs e) { { lblResult.Text = "Hello World"; lblResult.Text = "Hello World"; } } 20
  • 21. Lambda Expressions Lambda expression take the C# 2.0 anonymous method one step further C 2.0 btn.Click += delegate(object sender, EventArgs e) btn.Click += delegate(object sender, EventArgs e) { { lblResult.Text = "Hello!"; lblResult.Text = "Hello!"; } } C 3.0 btn.Click += (object sender, EventArgs e) => lblResult.Text = "Hello!"; btn.Click += (object sender, EventArgs e) => lblResult.Text = "Hello!"; -orbtn.Click += (sender, e) => lblResult.Text = "Hello!"; btn.Click += (sender, e) => lblResult.Text = "Hello!"; 21
  • 22. Lambda Expressions => goes into separates parameters from method body can drop parentheses when there is only one parameter 22
  • 23. LINQ – C# Equivalent LINQ queries query syntax var results = from c in Comedians where c.Contains("Marx") select c; method (lambda expression) syntax var results = Comedians.Where(c => c.Contains("Marx")); 23
  • 24. LINQ – VB Equivalent LINQ queries query syntax Dim results = From c In Comedians _ Where (c.Contains("Marx")) _ Select c method (lambda expression) syntax Dim results = Comedians.Where(Function(c) c.Contains("Marx")) 24
  • 25. LINQ – Hybrid Syntax You can also use a hybrid of query and method syntax often this is necessary because using query syntax alone is not expressive enough, especially when using C# var results = (from c in Comedians select c).Count(); 25
  • 26. LINQ to Objects If an object supports either IEnumerable or IEnumerable<T> interface, LINQ to Objects provider enables you to query it Array, ArrayList, collections, generic collections, … System.Linq namespace All examples shown so far have used LINQ to Objects 26
  • 27. LINQ to SQL System.Data.Linq namespace Works with SQL Server 2000/2005 Requires entity classes which you can build using the Object Relational Designer (ORD) Entity Framework will let you use LINQ with other databases using E-R data models 27
  • 28. Using ORD (1 of 3) Add to your App_Code folder 28
  • 29. Using ORD (2 of 3) 29
  • 30. Using ORD (3 of 3) Generated designer.cs file 30
  • 31. Binding to a LINQ Query Once the ORD created, you can reference its DataContext NorthwindDataContext db = new NorthwindDataContext(); var results = from cust in db.Customers where cust.Country == "USA" orderby cust.CompanyName select cust; gvCustomers.DataSource = results; gvCustomers.DataBind(); Example: CustomersGrid1.aspx 31
  • 32. Alternately… You can use LINQ data source Example: CustomersGrid2.aspx 32
  • 33. LINQ Tools LINQPad free tool for testing LINQ queries from Joseph Albahari http://www.linqpad.net/ LINQ Debug Visualizer free download from Microsoft http://www.scottgu.com/blogposts/linqquery/ sqlserverqueryvisualizer.zip 33
  • 34. Selecting Fields All fields (CustomersGrid1.aspx) var results = from cust in db.Customers select cust; Subset of fields –notice use of "new" to create anonymous type (CustomersGrid3.aspx) var results = from cust in db.Customers select new { cust.CompanyName, cust.ContactName, cust.City }; 34
  • 35. Filtering Data var results = from cust in db.Customers where (cust.Country == "USA" && (cust.CompanyName.ToLower().StartsWith("t") || cust.CustomerID.ToLower().StartsWith("t"))) orderby cust.CompanyName select cust; Filter1.aspx 35
  • 36. Using ORD Associations ORD automatically adds associations for database relationships var results = from c in db.Customers where c.Country == "USA" select new { c.CompanyName, c.City, TotalOrders = c.Orders.Count, LastOrder = c.Orders.Max(o => o.OrderDate) }; Association1.aspx 36
  • 37. Associations You can always get to 1st order associations Getting to 2nd and 3rd order associations requires you to compose your query so that you traverse 1—m relationships from the many side to the one side Contrast Association1.aspx, and Association2.aspx 37
  • 38. Ordering Data // ascending is default order var results = from cust in db.Customers orderby cust.Country, cust.Orders.Count descending select new { cust.Country, cust.City, cust.CompanyName, Orders = cust.Orders.Count }; Order1.aspx 38
  • 39. Joining Tables var results = from order in db.Orders join detail in db.Order_Details on order.OrderID equals detail.OrderID join product in db.Products on detail.ProductID equals product.ProductID join customer in db.Customers on order.CustomerID equals customer.CustomerID select new { customer.CompanyName, order.OrderDate, product.ProductName, detail.UnitPrice, Cost = detail.UnitPrice * detail.Quantity }; Join1.aspx 39
  • 40. Grouping Data from d in db.Order_Details from d in db.Order_Details group new group new { { order = d.Order, order = d.Order, detail = d, detail = d, customer = d.Order.Customer customer = d.Order.Customer } by d.Order.Customer.CompanyName into grpQuery } by d.Order.Customer.CompanyName into grpQuery select new select new { { Company = grpQuery.Key, Company = grpQuery.Key, Purchases = grpQuery.Count(), Purchases = grpQuery.Count(), FirstOrder = grpQuery.Min(g => g.order.OrderDate), FirstOrder = grpQuery.Min(g => g.order.OrderDate), LastOrder = grpQuery.Max(g => g.order.OrderDate), LastOrder = grpQuery.Max(g => g.order.OrderDate), TotalCost = grpQuery.Sum(g => g.detail.Quantity * g.detail.UnitPrice) TotalCost = grpQuery.Sum(g => g.detail.Quantity * g.detail.UnitPrice) }; }; Group1.aspx 40
  • 41. Calling Stored Procedure Drag sproc from Server Explorer to data model Call sproc as method of data context Example: CustomersFromSproc.aspx var customersByCountry = db.procCustomerSelectByCountry(ddlCountry.SelectedValue); gv.DataSource = customersByCountry; gv.DataBind(); 41
  • 42. Updating Data Can update, of course, using sprocs You can also use LinqDataSource control Example: UpdateCategories1.aspx You can also use an ObjectDataSource control against a Data Access Layer (DAL) Example: UpdateCategories2.aspx see excerpt in later slide This example also illustrates use of LINQ for SQL Server data paging 42
  • 44. Updating Data Example public void Update(CategoryDAL cat2Update) { var cat = (from c in db.Categories where (c.CategoryID == cat2Update.CategoryId) select c).Single(); cat.CategoryName = cat2Update.CategoryName; cat.Description = cat2Update.Description; db.SubmitChanges(); } 44
  • 45. SQL Server Data Paging public List<CategoryDAL> Select(int startRowIndex, int maximumRows) public List<CategoryDAL> Select(int startRowIndex, int maximumRows) { { var cat = (from category in db.Categories var cat = (from category in db.Categories orderby category.CategoryID orderby category.CategoryID select new select new { { category.CategoryID, category.CategoryID, category.CategoryName, category.CategoryName, category.Description category.Description }).Skip(startRowIndex).Take(maximumRows); }).Skip(startRowIndex).Take(maximumRows); List<CategoryDAL> catList = new List<CategoryDAL>(); List<CategoryDAL> catList = new List<CategoryDAL>(); foreach (var c in cat) foreach (var c in cat) { { CategoryDAL cd = new CategoryDAL(); CategoryDAL cd = new CategoryDAL(); cd.CategoryId = c.CategoryID; cd.CategoryId = c.CategoryID; cd.CategoryName = c.CategoryName; cd.CategoryName = c.CategoryName; cd.Description = c.Description; cd.Description = c.Description; catList.Add(cd); catList.Add(cd); } } return catList; return catList; } } 45
  • 46. Other LINQ Providers LINQ to XML LINQ to DataSets (aka LINQ to ADO.NET) LINQ to Entities 46
  • 47. LINQ to DataSets (aka LINQ to ADO.NET) Grab data from ADO.NET and put it into a DataSet, DataTable Use LINQ to shape the data 47
  • 48. LINQ to DataSet Example Example: LINQ2Dataset.aspx cnx = new SqlConnection(strCnx); cnx = new SqlConnection(strCnx); sda = new SqlDataAdapter("procCustomersSelect", cnx); sda = new SqlDataAdapter("procCustomersSelect", cnx); sda.SelectCommand.CommandType = CommandType.StoredProcedure; sda.SelectCommand.CommandType = CommandType.StoredProcedure; dt = new DataTable(); dt = new DataTable(); sda.Fill(dt); sda.Fill(dt); var cust = from c in dt.AsEnumerable() var cust = from c in dt.AsEnumerable() orderby c.Field<string>("ContactName") orderby c.Field<string>("ContactName") select new select new { { Contact = c.Field<string>("ContactName"), Contact = c.Field<string>("ContactName"), Company = c.Field<string>("CompanyName"), Company = c.Field<string>("CompanyName"), Location = c.Field<string>("City") + ", " + Location = c.Field<string>("City") + ", " + c.Field<string>("Country") c.Field<string>("Country") }; }; 48
  • 49. Other LINQ Providers LINQ to Entities Takes O/RM much further than LINQ to SQL Part of Visual Studio SP 1 49
  • 50. Discussion Points When are LINQ's strengths? What are its weaknesses? Is LINQ the future of data access in .NET? Or is the more "classic" N-tier, ADO.NET, stored procedures approach make more sense in many scenarios? 50
  • 51. LINQ Resources LINQPad http://www.linqpad.net/ LINQ Debug Visualizer http://www.scottgu.com/blogposts/linqquery/ sqlserverqueryvisualizer.zip Scott Guthrie's Blog http://weblogs.asp.net/scottgu/ 51
  • 52. Thank You! Slides and samples can be downloaded from www.deeptraining.com/litwin 52