Based on
May 2007
Pre-release
Code—
with Updates
Online!
INTRODUCING
MICROSOFT
®
LINQ
Paolo Pialorsi
Marco Russo
PUBLISHED BY
Microsoft Press
A Division of Microsoft Corporation
One Microsoft Way
Redmond, Washington 98052-6399
Copyright © 2007 by Microsoft Corporation
All rights reserved. No part of the contents of this book may be reproduced or transmitted in any form
or by any means without the written permission of the publisher.
Library of Congress Control Number: 2007924645
Printed and bound in the United States of America.
1 2 3 4 5 6 7 8 9 QWT 2 1 0 9 8 7
Distributed in Canada by H.B. Fenn and Company Ltd.
A CIP catalogue record for this book is available from the British Library.
Microsoft Press books are available through booksellers and distributors worldwide. For further information about international editions, contact your local Microsoft Corporation office or contact Microsoft
Press International directly at fax (425) 936-7329. Visit our Web site at www.microsoft.com/mspress.
Send comments to
Microsoft, Microsoft Press, Excel, IntelliSense, MSDN, SharePoint, SQL Server, Visual Basic, Visual
Studio, and Windows are either registered trademarks or trademarks of Microsoft Corporation in the
United States and/or other countries. Other product and company names mentioned herein may be the
trademarks of their respective owners.
The example companies, organizations, products, domain names, e-mail addresses, logos, people, places,
and events depicted herein are fictitious. No association with any real company, organization, product,
domain name, e-mail address, logo, person, place, or event is intended or should be inferred.
7KLVERRNH[SUHVVHVWKHDXWKRU¶VYLHZVDQGRSLQLRQV7KHLQIRUPDWLRQFRQWDLQHGLQWKLVERRNLVSURYLGHG
without any express, statutory, or implied warranties. Neither the authors, Microsoft Corporation, nor its
resellers, or distributors will be held liable for any damages caused or alleged to be caused either directly
or indirectly by this book.
Acquisitions Editor: Ben Ryan
Developmental Editor: Devon Musgrave
Project Editor: Valerie Woolley
Editorial and Production: John Pierce and Interactive Composition Corporation
Body Part No. X13-68390
Table of Contents
Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .vii
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix
1
LINQ Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1
What Is LINQ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
How LINQ Works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Relational Model vs. Hierarchical/Graph Model . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
XML Manipulation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Language Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Declarative Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Type Checking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Transparency Across Different Type Systems. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
LINQ Flavors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
LINQ to Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
LINQ to ADO.NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
LINQ to XML. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Present State and Future Direction of LINQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2
C# Language Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
C# 2.0 Revisited . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Generics. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Anonymous Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Enumerators and Yield . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
C# 3.0 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Local Type Inference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Lambda Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Extension Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Object Initialization Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
What do you think of this book?
We want to hear from you!
Microsoft is interested in hearing your feedback about this publication so we can
continually improve our books and learning resources for you. To participate in a brief
online survey, please visit: www.microsoft.com/learning/booksurvey/
iii
iv
Table of Contents
Anonymous Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Query Expressions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3
Visual Basic 9.0 Language Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Visual Basic 9.0 and Nullable Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Visual Basic 9.0 Features Corresponding to C# 3.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Local Type Inference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Extension Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Object Initialization Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Anonymous Types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Query Expressions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Lambda Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Closures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Visual Basic 9.0 Features Without C#3.0 Counterparts. . . . . . . . . . . . . . . . . . . . . . . . . 62
XML Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Relaxed Delegates. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
C# 3.0 Features Without Visual Basic 9.0 Counterparts . . . . . . . . . . . . . . . . . . . . . . . . 69
The yield Keyword. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Anonymous Methods. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
4
LINQ Syntax Fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
LINQ Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Query Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Full Query Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Query Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
The Where Operator. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Projection Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Ordering Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Grouping Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Join Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Set Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Aggregate Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Generation Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Quantifiers Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Partitioning Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Table of Contents
v
Element Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Other Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Deferred Query Evaluation and Extension Methods Resolution . . . . . . . . . . . . . . . . 115
Deferred Query Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Extension Methods Resolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Conversion Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
AsEnumerable. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
ToArray and ToList . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
ToDictionary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
ToLookup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
OfType and Cast. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
5
LINQ to ADO.NET. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
LINQ to SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Entities in LINQ to SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
Data Modeling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Data Querying . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Data Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Binding Metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Differences Between .NET and SQL Type Systems . . . . . . . . . . . . . . . . . . . . . . . 159
LINQ to DataSet. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
Using LINQ to Load a DataSet. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
Using LINQ to Query a DataSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
Using LINQ to Query a Typed DataSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Accessing Untyped DataSet Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
LINQ to Entities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
6
LINQ to XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
Introducing LINQ to XML. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
LINQ to XML API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
XElement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
XDocument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
XAttribute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
XNode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
XName and XNamespace. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Chapter 6
LINQ to XML
195
corresponding to the XPath expression provided as an argument, and the latter returns the
full list of elements matching the expression. Internally, they both use the XPathEvaluator
class. The following example selects all the customer elements of customers located in Italy:
var result = xmlCustomers.XPathSelectElements(
"/customer[@country = 'Italy']");
This method is sometimes useful for defining LINQ queries that work on a subset of nodes of
the source XML graph—in case we need to filter customer elements by the country attribute
value. An example is shown in Listing 6-41.
Listing 6-41
Sample LINQ query over the result of the XPathSelectElements extension method
var ordersOfItalianCustomersFromXml =
from
c in xmlCustomers.XPathSelectElements(
"/customer[@country = 'Italy']")
let
xName = (String)c.Element("name")
let
xCity = (String)c.Attribute("city")
join
o in orders
on
xName equals o.Name
orderby xName
select new {
Name = xName,
City = xCity,
IdProduct = o.IdProduct,
Quantity = o.Quantity };
Remember that XPath rules are checked at run time, not at compile time. Therefore, be careful
when defining them within LINQ queries. Consider also that like many other LINQ extension
methods, the XPath methods we have just evaluated also support deferred query evaluation.
Once again, keep in mind that every time we use queries defined using these methods, the
result is refreshed by rescanning the source XML graph, unless you copy it yourself by using
any of the extension methods provided by LINQ queries for doing that (such as ToList,
ToArray, ToDictionary, or ToLookup).
Summary
In this chapter, you saw how to define XML content using the LINQ to XML API—by means of
both functional construction and Visual Basic 9.0 XML literals. You also saw how to query,
traverse, and transform XML nodes graphs using LINQ to XML query extensions. Finally, you
evaluated the support offered by System.Xml.Linq to XPath, XSD, and XSLT.
INTRODUCING MICROSOFT LINQ
®
Your first look at building data-rich applications
using Microsoft LINQ.
Get a head start using Microsoft Language Integrated Query (LINQ). Two
experienced developers give you advance insights and expert guidance
for using this unified model for data access. You will learn how to write
queries in your native programming language—Microsoft Visual Basic®
or Visual C#®—using next-generation querying facilities in the Microsoft
.NET Framework.
Discover how to:
> Query and manipulate different data domains with a unified syntax
> Work with local type inference, lambda expressions, and extension
methods
> Use XML literals, late binding over XML, and relaxed delegates
About the Authors:
Paolo Pialorsi is a consultant, trainer,
and author specializing in developing
Web-based and distributed applications.
He is a founder of DevLeap, a company
focused on producing content for the professional
developer community. Paolo is the author of three
books on XML and Web services, and a regular
speaker at industry conferences.
Marco Russo is a founder of DevLeap
and a consultant and trainer who
specializes in the Microsoft .NET
Framework and Microsoft SQL Server™.
He is an active contributor to developer
communities, an avid blogger on Microsoft
technologies, and the author of two books on
the C# programming language and the common
language runtime.
> Query items using methods and generics in the System.Linq namespace
> Apply deferred query evaluation and extension methods resolution
> Query relational structures and physical models with LINQ to ADO.NET
> Convert queries into native SQL with LINQ to SQL
> Define and manage XML content by using LINQ to XML
Resource Roadmap
Developer Step by Step
Hands-on tutorial covering fundamental
techniques and features
O Practice files on CD
O Prepares and informs new-to-topic programmers
O
Developer Reference
Expert coverage of core topics
Extensive, pragmatic coding examples
O Builds professional-level proficiency
with a Microsoft technology
O
O
Get Visual Basic and Visual C# code samples
on the Web
For system requirements, see the Introduction.
Advanced Topics
O
O
O
Deep coverage of advanced techniques
and capabilities
Extensive, adaptable coding examples
Promotes full mastery of a Microsoft technology
For more information, see inside back cover.
Part No. X13-68400
microsoft.com/mspress
ISBN-13: 978-0-7356-2391-0
ISBN-10: 0-7356-2391-0
90000
U.S.A.
$34.99
[Recommended]
9
780735 623910
Programming/
Microsoft Visual Studio/LINQ