Pro LINQ free ebook download ee ee

  ® THE EXPERT’S VOICE

  Pro LINQ

  

Language Integrated Query in VB 2008

Learn to use the power of Microsoft’s ground-breaking new technology.

  Joseph C. Rattz, Jr. and

  Dennis Hayes

  Pro LINQ

Language Integrated Query

in VB 2008

Joseph C. Rattz, Jr. and Dennis Hayes

  Pro LINQ: Language Integrated Query in VB 2008 Copyright © 2009 by Joseph C. Rattz, Jr. and Dennis Hayes

All rights reserved. No part of this work may be reproduced or transmitted in any form or by any means,

electronic or mechanical, including photocopying, recording, or by any information storage or retrieval system, without the prior written permission of the copyright owner and the publisher.

  ISBN-13 (pbk): 978-1-4302-1644-5

  ISBN-13 (electronic): 978-1-4302-1645-2 Printed and bound in the United States of America 9 8 7 6 5 4 3 2 1

Trademarked names may appear in this book. Rather than use a trademark symbol with every occurrence

of a trademarked name, we use the names only in an editorial fashion and to the benefit of the trademark

owner, with no intention of infringement of the trademark. Lead Editor: Ewan Buckingham Technical Editor: Joseph C. Rattz, Jr. Technical Reviewers: Joseph C. Rattz, Jr., Fabio Ferracchiati Editorial Board: Clay Andres, Steve Anglin, Mark Beckner, Ewan Buckingham, Tony Campbell,

  Gary Cornell, Jonathan Gennick, Michelle Lowman, Matthew Moodie, Jeffrey Pepper, Frank Pohlmann, Ben Renow-Clarke, Dominic Shakeshaft, Matt Wade, Tom Welsh Project Manager: Richard Dal Porto Copy Editor: Heather Lang Associate Production Director: Kari Brooks-Copony Production Editor: Kelly Winquist Compositors: Dina Quan, Patrick Cunningham Proofreader: April Eddy Indexer: Carol Burbo Artist: April Milne Cover Designer: Kurt Krames Manufacturing Director: Tom Debolski

Distributed to the book trade worldwide by Springer-Verlag New York, Inc., 233 Spring Street, 6th Floor,

New York, NY 10013. Phone 1-800-SPRINGER, fax 201-348-4505, e-mail kn`ano)ju<olnejcan)o^i*_ki, or

visit dppl6++sss*olnejcankjheja*_ki. For information on translations, please contact Apress directly at 2855 Telegraph Avenue, Suite 600, Berkeley, CA 94705. Phone 510-549-5930, fax 510-549-5939, e-mail ejbk<]lnaoo*_ki, or visit dppl6++sss* ]lnaoo*_ki. Apress and friends of ED books may be purchased in bulk for academic, corporate, or promotional use.

eBook versions and licenses are also available for most titles. For more information, reference our Special

Bulk Sales–eBook Licensing web page at dppl6++sss*]lnaoo*_ki+ejbk+^qhgo]hao.

  

The information in this book is distributed on an “as is” basis, without warranty. Although every precau-

tion has been taken in the preparation of this work, neither the author(s) nor Apress shall have any liability

to any person or entity with respect to any loss or damage caused or alleged to be caused directly or indi-

rectly by the information contained in this work.

  

The source code for this book is available to readers at dppl6++sss*]lnaoo*_ki. You may need to answer

questions pertaining to this book in order to successfully download the code.

  

To my father-in-law, Samuel Arthur Sanders, I dedicate this book. Art Sanders was my

most supportive cheerleader while I was working on Pro LINQ: Language Integrated Query

  in C# 2008. Unfortunately, Art’s health began to fail toward the end of that book, and for

  

a while, it seemed doubtful he would live to see it completed. Not one to give up, Art over-

came numerous hospitalizations and did indeed receive his personally signed copy.

  

Sadly, Art will never see this book because he passed away on February 25, 2009, at the

age of 80. Rest in peace, Art. Contents at a Glance

About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  ฀ ฀

  

PART 1 Pro LINQ: Language Integrated Query

in VB.NET 2008

  . . . . . . . . . . . . . . . . .

  VB.NET 2008 Language Enhancements for LINQ ฀ ฀

  PART 2 LINQ to Objects CHAPTER 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ฀ ฀

  PART 3 LINQ to XML CHAPTER 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv

  v

  Part 4 ฀ ฀

  LINQ to DataSet

  CHAPTER 10 LINQ to DataSet Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Part 5 ฀ ฀

  LINQ to SQL

  CHAPTER 12 LINQ to SQL Introduction

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  CHAPTER 13 LINQ to SQL Tips and Tools

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  CHAPTER 14 LINQ to SQL Database Operations

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  CHAPTER 15 LINQ to SQL Entity Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CHAPTER 17 Concurrency Conflicts

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  CHAPTER 18 Additional SQL Capabilities

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Contents About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  ฀ ฀

  PART 1 Pro LINQ: Language Integrated Query in VB.NET 2008 CHAPTER 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii

  viii C O N T E N T S

  CHAPTER 2

  . . . . . . . . . .

VB.NET 2008 Language Enhancements for LINQ

  New VB.NET 2008 Language Additions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Option Explicit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Option Strict . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Lambda Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Lambda Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Keyword Dim, Object Initialization, and Anonymous Types . . . . . . . The Implicitly Typed Local Variable Keyword Dim (with Option Infer On/Option Strict On) . . . . . . . . . . . . . . . . .

  Anonymous Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Instance (Object) vs. Shared (Class) Methods Recap . . . . . . . . The Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Extension Method Precedence . . . . . . . . . . . . . . . . . . . . . . . . . . . A Partial Method Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Query Expression Grammar . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Nullable Value Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  XML Enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  XML Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  XML Embedded Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  XML Axis Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  XML Namespace Imports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  C O N T E N T S ix

  PART 2 ฀ ฀

  LINQ to Objects

  x C O N T E N T S Join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  GroupJoin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . GroupBy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Distinct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Intersect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . OfType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Repeat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  xi C O N T E N T S

  SingleOrDefault . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ElementAtOrDefault . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Any . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Contains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Max . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Aggregate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  ฀ ฀

  PART 3 LINQ to XML CHAPTER 6 LINQ to XML Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Additional Advantages of LINQ to XML

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Cheating the W3C DOM XML API

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Summary

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Significant API Design Enhancements

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  XML Tree Construction Simplified with Functional Construction

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Document Centricity Eliminated in Favor of Element Centricity

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Names, Namespaces, and Prefixes

  . . . . . . . . . . . . . . . . . . . . . . . . . .

  Node Value Extraction

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  The LINQ to XML Object Model

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Deferred Query Execution, Node Removal, and the Halloween Problem

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  xii C O N T E N T S

  XML Creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating Elements with XElement . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating Comments with XComment . . . . . . . . . . . . . . . . . . . . . . . . . Creating Declarations with XDeclaration . . . . . . . . . . . . . . . . . . . . . . Creating Documents with XDocument . . . . . . . . . . . . . . . . . . . . . . . . Creating Namespaces with XNamespace . . . . . . . . . . . . . . . . . . . . . Creating Processing Instructions with XProcessingInstruction . . . Creating Text with XText . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  XML Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Saving with XElement.Save() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  XML Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Loading with XElement.Load() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  XML Traversal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Forward with XNode.NextNode . . . . . . . . . . . . . . . . . . . . . . . . . Up to Document with XObject.Document . . . . . . . . . . . . . . . . .

  Traversal Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Down with XContainer.Elements() . . . . . . . . . . . . . . . . . . . . . . . Up Recursively with XNode.Ancestors() . . . . . . . . . . . . . . . . . . Down Recursively with XContainer.Descendants() . . . . . . . . . Forward with XNode.NodesAfterSelf() . . . . . . . . . . . . . . . . . . . . Backward with XNode.NodesBeforeSelf() . . . . . . . . . . . . . . . .

  xiii C O N T E N T S

  XML Modification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  

XContainer.Add() (AddLast) . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  

XContainer.AddFirst() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  

XNode.AddBeforeSelf() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  

XNode.AddAfterSelf() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  

XNode.Remove() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  

IEnumerable(Of T).Remove() . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  

XElement.RemoveAll() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  XElement.Value on XElement Objects, XText.Value on XText Objects, and XComment.Value on

  XComment Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  XDocumentType.Name, XDocumentType.PublicId, XDocumentType.SystemId, and XDocumentType.

  InternalSubset on XDocumentType Objects . . . . . . . . . . . .

  XProcessingInstruction.Target on XProcessingInstruction Objects and XProcessingInstruction.Data on

  XProcessingInstruction Objects . . . . . . . . . . . . . . . . . . . . . .

  

XElement.ReplaceAll() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  XElement.SetElementValue() on Child XElement Objects . . . . . . . .

  XML Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Attribute Traversal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  

Forward with XAttribute.NextAttribute . . . . . . . . . . . . . . . . . . .

Backward with XElement.LastAttribute . . . . . . . . . . . . . . . . . .

  

XElement.Attribute() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  

XElement.Attributes() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Adding Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Updating Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  

XElement.SetAttributeValue() . . . . . . . . . . . . . . . . . . . . . . . . . . .

  XML Annotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Accessing Annotations with XObject.Annotation() or

  

XObject.Annotations() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  xiv C O N T E N T S Removing Annotations with XObject.RemoveAnnotations() . . . . . .

  XML Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  XObject.Changing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  XObject.Changed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Trick or Treat, or Undefined? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  C O N T E N T S xv

  Nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  CHAPTER 9 Additional XML Capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PART 4 ฀ ฀

LINQ to DataSet

  CHAPTER 10 LINQ to DataSet Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Assembly References

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Referenced Namespaces

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Common Code for the Examples

  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  xvi C O N T E N T S DataRow Set Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Except . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Union . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  DataRow Field Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  SetField(Of T) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  AsEnumerable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  xvii C O N T E N T S

  ฀ ฀

  PART 5 LINQ to SQL CHAPTER 12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  C O N T E N T S xviii Adding Objects to the Entity Class Model . . . . . . . . . . . . . . . . .

  Use SqlMetal and the O/R Designer Together . . . . . . . . . . . . . . . . . . . . . .

  C O N T E N T S xix

  XML External Mapping File Schema . . . . . . . . . . . . . . . . . . . . . . . . . .

Prefer Object Initialization to Parameterized

Construction When Projecting . . . . . . . . . . . . . . . . . . . . . . . .

  Extending Entity Classes with Partial Methods . . . . . . . . . . . . . . . . . . . . . . EntitySet(Of T) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Entity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Table(Of T) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  IExecuteResult . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . GetParameterValue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  ISingleResult(Of T) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  IMultipleResults . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . GetResult(Of T) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

CHAPTER 16 The DataContext . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599 Prerequisites for Running the Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 599 Some Common Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599 Using the LINQ to SQL API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599

  [Your]DataContext Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The DataContext Class Implements IDisposable . . . . . . . . . . . . . . .

  Identity Tracking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Change Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  DataContext() and [Your]DataContext() . . . . . . . . . . . . . . . . . . . . . . . . Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  SubmitChanges() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  xx C O N T E N T S DatabaseExists() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  DeleteDatabase() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  ExecuteQuery() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  ExecuteCommand() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  GetCommand() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  GetTable() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  xxi C O N T E N T S

About the Author JOSEPH C. RATTZ, JR

  unknowingly began his career in software development in 1990 when a friend asked him for assistance writing an ANSI text editor named ANSI Master for the Com- modore Amiga. A hangman game (The Gallows) soon followed. From these compiled Basic programs, he moved on to programming in C for more speed and power. Joe then developed applications that were sold to JumpDisk, an Amiga disk magazine, as well as Amiga World magazine. Due to developing in a small town on a fairly isolated platform, Joe learned all the wrong ways to write code. It was while trying to upgrade his poorly written applications that he gained respect for the importance of easily maintainable code. It was love at first sight when Joe spotted a source-level debugger in use for the first time.

  Two years later, Joe obtained his first software development opportunity at Policy Management Systems Corporation as an entry-level programmer developing a client/server insurance application for OS/2 and Presentation Manager. Through the years, he added C++, Unix, Java, ASP, ASP.NET, C#, HTML, DHTML, and XML to his skill set while develop- ing applications for SCT, DocuCorp, IBM and the Atlanta Committee for the Olympic Games, CheckFree, NCR, EDS, Delta Technology, Radiant Systems, and the Genuine Parts Company. Joe enjoys the creative aspects of user interface design, and he appreciates the discipline nec- essary for server-side development. But, given his druthers, his favorite development pastime is debugging code.

  Joe can be found working for the Genuine Parts Company—the parent company of NAPA—in the Automotive Parts Group Information Systems department, where he works on his baby, the Storefront web site. This site for NAPA stores provides a view into their accounts and data on a network of AS/400s.

  Joe’s first book, Pro LINQ: Language Integrated Query in C# 2008, was published on November 19, 2007, which is the exact same date that Visual Studio 2008 was released to man- ufacturing. One final LINQ coincidence is that Visual Studio 2008 was officially launched on February 27, 2008, which just happens to be Joe’s birthday.

  Joe can be reached at his web site, sss*hejm`ar*_ki.

  xxiii

  About the Technical Reviewer

  is a senior consultant and a senior analyst/developer using Microsoft technologies. He works for Brain Force ( sss*^n]ejbkn_a*_ki) in its Italian branch ( sss*^n]ejbkn_a*ep). He is a Microsoft Certified Solution Developer for .NET, a Microsoft Cer- tified Application Developer for .NET, a Microsoft Certified Professional, and a prolific author and technical reviewer. Over the past ten years, he’s written articles for Italian and interna- tional magazines and coauthored more than ten books on a variety of computer topics. You can read his LINQ blog at sss*bann]__de]pe*_ki.

  xxv

  Acknowledgments

  ell, it appears that it is time to write the acknowledgments for another book. Readers of

W

  Pro LINQ: Language Integrated Query in C# 2008 may recall the endless delays in publishing that book. A project that initially started as a 9-month project grew into a 17-month project.

  This book turned out to be no less challenging in terms of scheduling and delays. If you were one of those who patiently waited for this book to be published, I want to thank you for your patience. I hope you find it worth the wait.

  When I wrote the acknowledgments for my C# LINQ book, I expected that to be my single opportunity to show my appreciation to all those people who made the book possible. I did not imagine that I would have another opportunity to write acknowledgments, so I spilled my guts on the first one. Obviously, most of the people who made the C# book possible also made this one possible. The beauty of writing this book’s acknowledgments is that I have the luxury of getting to correct any errors of omission that occurred in the first book’s Acknowledgments.

  The first person that I want to thank is my wife, Vickey. I mentioned in the first book that she had to do many of my chores during the 17 months I worked on it. Then, a mere 7 months after it was published, I was engaged in yet another book—for a year. She has waited more than long enough for us to resume a normal life. I have promised her that I will straighten the basement before I begin any more books. So this may be my last.

  I would like to thank Apress for another opportunity to write a book. Specifically, I want to thank Ewan Buckingham. I can’t help but think I have taken years off his life. Richard Dal Porto performed project management duties for this book and with chapters flying about, it is amazing that he could keep it all straight. Heather Lang handled the role of copy editor. She also took over the reins as copy editor on my C# LINQ book, so I have been twice privileged to have her make my writing look coherent, well-formed, and written in a language consist- ing of characters other than commas. Sadly, I still haven’t learned when to use commas. Kelly Winquist was the production editor for this book, and I certainly appreciate her and her team’s effort, which is apparent when you get to see the finished product. I turn in Microsoft Word documents, and a book comes out on the other side. It is a fabulous machine! Thank you April Eddy for proofreading the book once I was finished with it. I know there are unnamed others who worked on this book, and while you don’t get to see your name here, you get the more valuable benefit of probably never having had an interaction with me. Kudos to you too!

  Next, I must extend my appreciation to Fabio Ferracchiati. Not only did he perform the technical reviewer duties, he filled in as stunt author. This book still might not be finished were it not for his assistance.

  In the C# book’s acknowledgments, I thanked Anders Hejlsberg for the vision from which LINQ grew. Since that time, I have come to realize that I significantly short-changed Erik Meijer. Erik, I apologize for that. From what I know now, it is quite clear that LINQ would not exist without him. If instead of naming the new technology LINQ, he had named it Enumerable Restricting Integrated Kwery, I would have known.

  xxvii

  xxviii A C K N O W L E D G M E N T S

  I want to thank the Microsoft VB language team for wonderful LINQ support being added to the language. Your VB.NET XML enhancements are enough to make this C# programmer envious. I hope the C# design team was paying attention.

  Again, I must thank my parents: my dad for giving me the confidence to think I could actually write a book, and my mom for her constant input of ideas. Last, I want to thank all the readers of the C# LINQ book who sent in comments, sug- gestions, and corrections. Specifically, I want to thank Jon Skeet and Judson White for their much-appreciated effort. Both of these fine developers took the time to send me detailed notes. This book is better because of their efforts.

  Joseph C. Rattz, Jr.

P A R T 1

  

Pro LINQ: Language

Integrated Query in

  C H A P T E R 1 Hello LINQ Listing 1-1.

  Hello LINQ

  Klpekj Atlhe_ep Kj Klpekj Ejban Kj Klpekj Opne_p Kj Eilknpo Ouopai Eilknpo Ouopai*Hejm Ik`qha Ik`qha- Oq^ I]ej$% @ei cnaapejco$% =o Opnejc 9 w dahhk sknh` ( dahhk HEJM ( dahhk =lnaoo y @ei epaio 9 [ Bnki o Ej cnaapejco [ Sdana o*Aj`oSepd$ HEJM % [ Oaha_p o Bkn A]_d epai Ej epaio ?kjokha*SnepaHeja$epai% Jatp epai Aj` Oq^ Aj` Ik`qha

  Note The code in Listing 1-1 is a complete console program created in Visual Studio 2008. In most

  places, I will leave out the Ik`qha, Oq^ I]ej, and common Eilknpo statements, but I will include any unusual Eilknpo that an example requires.

  Running the previous code by pressing Ctrl+F5 outputs the following data to the console window:

  3 dahhk HEJM

  Note Also note that, in most cases, you do not need to have the common Eilknpo statements in

  your code, because VB.NET adds them behind the scenes at compile time. You can see (and modify) the list of namespaces added by looking in the project’s Properties, on the Reference tab, in the “Imported namespaces” table.

A Paradigm Shift

  Did you just feel your world shift? As a .NET developer, you should have. With the trivial pro- gramming example in Listing 1-1, you just ran what somewhat appears to be a Structured 1 Query Language (SQL) query on an array of strings. Check out that sdana clause. Did you notice that I used the Aj`oSepd method of a Opnejc object? You may be wondering why, with Klpekj Opne_p Kj, an error was not generated when I declared epaio without a type or when I used epai as a variable in the Bkn A]_d loop without giving it a type. To those used to pro- gramming in VB6 or VB.NET with Klpekj Atlhe_ep and Klpekj Opne_p set to Kbb, declaring a variable without giving it a type may not seem like a big deal. But with Klpekj Opne_p Kj, it is. Explaining why we do not get a compilation error from this would be a distraction right now, but I will pick up this idea again at the start of Chapter 2. So, what features of VB.NET are allowing all of this? The answer is Microsoft’s Language Integrated Query, otherwise known as LINQ.

Query XML

  While the example in Listing 1-1 is trivial, the example in Listing 1-2 may begin to indicate the potential power that LINQ puts into the hands of the .NET developer. It displays the ease with which one can interact with and query Extensible Markup Language (XML) data utilizing the LINQ to XML API. You should pay particular attention to how I construct the XML data into an object named ^kkgo that I can programmatically interact with.

  Listing 1-2. A Simple XML Query Using LINQ to XML

  Eilknpo Ouopai Eilknpo Ouopai*Hejm Eilknpo Ouopai*Tih*Hejm @ei ^kkgo =o TAhaiajp 9 [ 8^kkgo:

  1. Most noticeably, the order is inverted from typical SQL. Additionally, there is the added “s In” portion of the query that provides a reference to the set of elements contained in the source, which in this case is the array of strings “hello world”, “hello LINQ”, and “hello Apress”.

  5 C H A P T E R 1 H E L L O L I N Q ฀

  8^kkg: 8pepha:Lnk HEJM6 H]jcq]ca Ejpacn]pa` Mqanu ej R>*JAP .,,48+pepha: 8]qpdkn:@ajjeo D]uao8+]qpdkn: 8+^kkg: 8^kkg: 8pepha:Lnk SB6 Sej`kso Skngbhks ej *JAP /*18+pepha: 8]qpdkn:>nq_a >qgkre_o8+]qpdkn: 8+^kkg: 8^kkg: 8pepha:Lnk ? .,,4 ]j` pda *JAP /*1 Lh]pbkni( Bkqnpd A`epekj8+pepha: 8]qpdkn:=j`nas Pnkahoaj8+]qpdkn: 8+^kkg: 8+^kkgo: #?Opn _]op jkp jaa`a` eb Klpekj Opne_p eo kbb @ei pephao 9 [ Bnki ^kkg Ej ^kkgo*Ahaiajpo$ ^kkg % [ Sdana ?Opn$^kkg*Ahaiajp$ ]qpdkn %% 9 @ajjeo D]uao [ Oaha_p ^kkg*Ahaiajp$ pepha % Bkn A]_d pepha Ej pephao ?kjokha*SnepaHeja$pepha*R]hqa% Jatp pepha

  Note

  The code in Listing 1-2 requires adding the Ouopai*Tih*Hejm*`hh assembly to the project refer- ences if it is not already added. Also notice that I added an Eilknpo statement for the Ouopai*Tih*Hejm namespace.

  Running the previous code by pressing Ctrl+F5 outputs the following data to the console window: Lnk HEJM6 H]jcq]ca Ejpacn]pa` Mqanu ej R>*JAP .,,4

  Did you notice how I simply loaded the XML data into an object of type TAhaiajp? Among the new features in VB.NET 2008 are XML literals, where a block of XML can be assigned to an XML element. I will cover this in more detail in Chapter 2. Also, LINQ to XML expands the

  XML API with its richer API. While the W3C Document Object Model (DOM) XML API requires Tih@k_qiajp-centric development, LINQ to XML allows the developer to interact at the ele- ment level using the TAhaiajp class. The LINQ to XML API will be covered in Chapter 7.

  Note

  In addition to query features, LINQ to XML provides a more powerful and easier-to-use interface for working with XML data. Again notice that I utilized the same SQL-like syntax to query the XML data, as though it were a database.

  Query a SQL Server Database 2 My next example shows how to use LINQ to SQL to query database tables. In Listing 1-3, I query the standard Microsoft Northwind sample database.

  Listing 1-3.

  A Simple Database Query Using LINQ to SQL

  Eilknpo Ouopai Eilknpo Ouopai*Hejm Eilknpo Ouopai*@]p]*Hejm Eilknpo ?d]lpan-*jsej` @ei `^ =o Jas Jknpdsej`$ [ @]p] Okqn_a9*XOMHATLNAOO7Ejepe]h ?]p]hkc9Jknpdsej`7Ejpacn]pa` Oa_qnepu9OOLE7 % @ei _qopo 9 [ Bnki _ Ej `^*?qopkiano [ Sdana _*?epu 9 Nek `a F]jaenk [ Oaha_p _ Bkn A]_d _qop Ej _qopo ?kjokha*SnepaHeja$ w,y ( _qop*?kil]juJ]ia% Jatp _qop

  Note

  The code in Listing 1-3 requires adding the Ouopai*@]p]*Hejm*`hh assembly to the project refer- ences if it is not already added. Also notice that I added an Eilknpo statement for the Ouopai*@]p]*Hejm namespace.

  When working with the files generated by SqlMetal, you need to use namespaces and Eilknpo state- ments that are appropriate for the way to set up your project. Depending on how you set up your project, you may need to include the project’s default namespace, such as Eilknpo ?d]lpan-*jsej`, just the gener- ated namespace, Eilknpo jsej`, or you may not need any Eilknpo statement at all. I cover this in more detail in Chapter 2.

  You can see that I added an Eilknpo statement for the ?d]lpan-*jsej` namespace. For this example to work, you must use the SqlMetal command-line utility, or the Object Relational Designer, to generate entity classes for the targeted database, which in this example is the Microsoft Northwind sample database. See Chapter 12 to read how this is done with SqlMetal.

  7 C H A P T E R 1 H E L L O L I N Q ฀

  The generated entity classes are created in the jsej` namespace, which I specify when gen- erating them. I then add the SqlMetal generated source module to my project and add the Eilknpo statement for the jsej` namespace.

  Note

  You may need to change the connection string that is passed to the Jknpdsej` constructor in Listing 1-3 for the connection to be properly made. Read the section on @]p]?kjpatp$% and WUkqnY@]p]?kjpatp$% in Chapter 16 to see different ways to connect to the database.

  Running the previous code by pressing Ctrl+F5 outputs the following data to the console window: D]j]ne ?]njao Mqa @ahŽ_e] Ne_]n`k =`k_e_]`ko

  This simple example demonstrates querying the Customers table of the Northwind data- base for customers in Rio de Janeiro. While it may appear that there is nothing new or special going on here that I wouldn’t already have with existing means, there are some significant differences. Most noticeably, this query is integrated into the language, and this means I get language-level support, which includes syntax checking and IntelliSense. Gone will be the days of writing a SQL query into a string and not detecting a syntax error until runtime. Want to make your sdana clause dependent on a field in the Customers table but you cannot remember the name of the field? IntelliSense will show the table’s fields to you. Once you type

  c. in the previous example, IntelliSense will display all the fields of the Customers table to you.

  All of the previous queries use the query expression syntax. You will learn in Chapter 2 that there are two syntaxes available for LINQ queries, of which the query expression syntax is one. Of course, you may always use the standard dot notation syntax that you are accustomed to seeing in .NET instead. This syntax is the normal k^fa_p*iapdk`$% invocation pattern you have always been using.

Introduction to LINQ

  As the Microsoft .NET platform, and its supporting languages C# and VB.NET, have matured, it has become apparent that one of the more troublesome areas still remaining for developers is that of accessing data from different data sources. In particular, database access and XML manipulation are often cumbersome at best, and problematic in the worst cases.

  The database problems are numerous. First, there is the issue that we cannot program- matically interact with a database at the native language level. This means syntax errors often go undetected until runtime. Incorrectly referenced database fields are not detected either. This can be disastrous, especially if this occurs during the execution of error-handling code. Nothing is more frustrating than having an entire error-handling mechanism fail because of syntactically invalid code that has never been tested. Sometimes this is unavoidable due to unanticipated error behavior. Having database code that is not validated at compile time can certainly lead to this problem.

  A second problem is the nuisance caused by the differing data types utilized by a par- ticular data domain, such as database or XML data types vs. the native language in which the program is written. In particular, dates and times can be quite a hassle.

  XML parsing, iterating, and manipulation can be quite tedious. Often an XML fragment is all that is desired, but due to the W3C DOM XML API, an Tih@k_qiajp must be created just to perform various operations on the XML fragment.

  Rather than just add more classes and methods to address these deficiencies in a piece- meal fashion, the development team at Microsoft decided to go one step further by abstracting the fundamentals of data query from these particular data domains. The result was LINQ. LINQ is Microsoft’s technology to provide a language-level support mechanism for querying data of all types. These types include in-memory arrays and collections, databases, XML docu- ments, and more.

LINQ Is About Data Queries

  For the most part, LINQ is all about queries, whether they are queries returning a set of matching objects, a single object, or a subset of fields from an object or set of objects. In LINQ, this returned set of objects is called a sequence. Most LINQ sequences are of type EAjqian]^ha$Kb P%, where P is the data type of the objects stored in the sequence. For example, if you have a sequence of integers, they would be stored in a variable of type EAjqian]^ha$Kb Ejpacan%. You will see that EAjqian]^ha$Kb P% runs rampant in LINQ. Many of the LINQ meth- ods return an EAjqian]^ha$Kb P%.

  In the previous examples, all of the queries actually return an EAjqian]^ha$Kb P% or a type that inherits from EAjqian]^ha$Kb P%. However, I declare the variables without types for the sake of simplicity at this point. This is unrelated to the old VB6 R]ne]jp or to how VB.NET has handled untyped variables prior to VB.NET 2008, because these variables are given a specific type by VB.NET. I will cover this in detail in Chapter 2, where you will see examples that begin demonstrating that sequences are truly stored in variables implementing the EAjqian]^ha$Kb P% interface.

Components

  Because LINQ is so powerful, you should expect to see a lot of systems and products become LINQ compatible. Virtually any data store would make a good candidate for supporting LINQ queries. This includes databases, Microsoft’s Active Directory, the registry, the file system, an Excel file, and so on.

  Microsoft has already identified the components in this section as necessary for LINQ. There is no doubt that there will be more to come.

  LINQ to Objects

  LINQ to Objects is the name given to the EAjqian]^ha$Kb P% API for the Standard Query Oper- ators. It is LINQ to Objects that allows you to perform queries against arrays and in-memory data collections. Standard Query Operators are the static methods of the static Ouopai*Hejm* Ajqian]^ha class that you use to create LINQ to Objects queries.

  9 C H A P T E R 1 H E L L O L I N Q ฀ LINQ to XML

  LINQ to XML is the name given to the LINQ API dedicated to working with XML. This interface was known as XLinq in older prereleases of LINQ. Not only has Microsoft added the neces- sary XML libraries to work with LINQ, it has addressed other deficiencies in the standard XML DOM, thereby making it easier than ever to work with XML. Gone are the days of having to cre- ate an Tih@k_qiajp just to work with a small piece of XML. To take advantage of LINQ to XML, you must have a reference to the Ouopai*Tih*Hejm*`hh assembly in your project and have an Eilknpo statement such as the following: Eilknpo Ouopai*Tih*Hejm

  LINQ to DataSet