Tải bản đầy đủ (.pdf) (585 trang)

Pro ADO net 2 0

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (7.5 MB, 585 trang )


5122chFM.qxd

8/23/05

3:44 PM

Page i

Pro ADO.NET 2.0

Sahil Malik


5122chFM.qxd

8/23/05

3:44 PM

Page ii

Pro ADO.NET 2.0
Copyright © 2005 by Sahil Malik
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: 1-59059-512-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: Jonathan Hassell
Technical Reviewers: Frans Bouma and Erick Sgarbi
Editorial Board: Steve Anglin, Dan Appleman, Ewan Buckingham, Gary Cornell, Tony Davis, Jason Gilmore,
Jonathan Hassell, Chris Mills, Dominic Shakeshaft, Jim Sumser
Associate Publisher: Grace Wong
Project Manager: Emily K. Wolman
Copy Edit Manager: Nicole LeClerc
Copy Editor: Linda Marousek
Assistant Production Director: Kari Brooks-Copony
Production Editor: Ellie Fountain
Compositor: Kinetic Publishing Services, LLC
Proofreader: April Eddy
Indexer: Carol Burbo
Artist: Kinetic Publishing Services, LLC
Interior Designer: Van Winkle Design Group
Cover Designer: Kurt Krames
Manufacturing Manager: 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 , or
visit .
For information on translations, please contact Apress directly at 2560 Ninth Street, Suite 219, Berkeley,
CA 94710. Phone 510-549-5930, fax 510-549-5939, e-mail , or visit .
The information in this book is distributed on an “as is” basis, without warranty. Although every precaution 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
indirectly by the information contained in this work.
The source code for this book is available to readers at in the Source Code section.


5122chFM.qxd


8/23/05

3:44 PM

Page iii

I would like to dedicate this book to my parents.
Mom, for being extremely strict with me when I was a kid
and always very loving in all my years.
Pop, for saving me from Mom ;-),
and being the neverending source of inspiration and strength.
I love you both very much.


5122chFM.qxd

8/23/05

3:44 PM

Page iv


5122chFM.qxd

8/23/05

3:44 PM

Page v


Contents at a Glance
About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
About the Technical Reviewers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi

■CHAPTER
■CHAPTER
■CHAPTER
■CHAPTER
■CHAPTER
■CHAPTER
■CHAPTER
■CHAPTER
■CHAPTER
■CHAPTER
■CHAPTER
■CHAPTER
■CHAPTER
■CHAPTER

1
2
3
4
5
6
7
8

9
10
11
12
13
14

An Introduction to ADO.NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
The ADO.NET Object Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
ADO.NET Hello World! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Connecting to a Data Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Retrieving Data in a Connected Fashion . . . . . . . . . . . . . . . . . . . . . . . . 77
DataSets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Fetching Data: The DataAdapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
Sorting, Searching, and Filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
Updating Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Updating Data: Advanced Scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
XML and ADO.NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
The CLR in SQL Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461
ADO.NET Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513

■INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529

v


5122chFM.qxd

8/23/05


3:44 PM

Page vi


5122chFM.qxd

8/23/05

3:44 PM

Page vii

Contents
About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
About the Technical Reviewers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi

■CHAPTER 1

An Introduction to ADO.NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
What Is ADO.NET? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
What Is Wrong with ADO? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Meeting the Players: Important Objects in ADO.NET . . . . . . . . . . . . . . . . . . . 4
The Connected Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
The Disconnected Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
.NET Data Providers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Using the ProviderBase Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

Third-Party .NET Data Providers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
The System.Data.Design Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

■CHAPTER 2

The ADO.NET Object Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
This Is a Reference Chapter. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
10,000-Ft. View of ADO.NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Establishing a Connection: DbConnection . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Executing a Command: DbCommand and DbTransaction . . . . . . . . . . . . . 19
Creating Parameterized Commands: DbParameter . . . . . . . . . . . . . . 20
Holding Disconnected Data: DataSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Fetching Data: Data Reader and Data Adapter . . . . . . . . . . . . . . . . . . . . . . . 24
The Connected Way to Fetch Data: DbDataReader . . . . . . . . . . . . . . 24
The Bridge Between Connected and Disconnected:
DbDataAdapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Exceptions in ADO.NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

vii


5122chFM.qxd

viii

8/23/05

3:44 PM


Page viii

■CONTENTS

■CHAPTER 3

ADO.NET Hello World! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Setting Up the Hello World Data Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Creating a Data-Driven Application: The Drag-and-Drop Approach . . . . . 32
Drag and Drop in ASP.NET 2.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Drag and Drop in a Windows Forms Application . . . . . . . . . . . . . . . . 39
Hybrid Approach: Write Some Code, Do Some Drag and Drop . . . . . . . . . 45
Data-Driven Application: The “Write Code Yourself” Approach . . . . . . . . . 48
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

■CHAPTER 4

Connecting to a Data Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
The Ability to Connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Creating Connection Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Generating Provider-Specific Connection Strings . . . . . . . . . . . . . . . 57
The Easy Way to Any Connection String. . . . . . . . . . . . . . . . . . . . . . . . 60
Securing Connection Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
The Common Behavior: IDbConnection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
The Common Logic: DbConnection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
High-Demand Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Connection Pooling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
So How Does It All Work? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Deciding on the Right Pool Size. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

Corrupt Connection Pools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Closing Connections: Good Application Design . . . . . . . . . . . . . . . . . . . . . . 74
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

■CHAPTER 5

Retrieving Data in a Connected Fashion

. . . . . . . . . . . . . . . . . . 77

Communicating with the Data Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Retrieving a Scalar Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Which Database to Execute Against . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
What to Execute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Executing a Command to Retrieve Results . . . . . . . . . . . . . . . . . . . . . 82
Retrieving a Result Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Querying a Result Set for Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Querying Large Result Sets Asynchronously . . . . . . . . . . . . . . . . . . . . . . . . 91
Querying the Database for Multiple Result Sets . . . . . . . . . . . . . . . . . . . . . 96
Object-Oriented vs. Relational Representation . . . . . . . . . . . . . . . . . . . . . . . 99
Storing Objects in the Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Querying for UDT Data Using SQL. . . . . . . . . . . . . . . . . . . . . . . . . . . . 105


5122chFM.qxd

8/23/05

3:44 PM


Page ix

■CONTENTS

Retrieving UDT Data in a Connected Fashion . . . . . . . . . . . . . . . . . . 105
Pragmatic Use of UDTs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107

■CHAPTER 6

DataSets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
The Case for the Disconnected Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
The DataSet Object Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
DataTable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
DataColumn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
DataRow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Setting a Primary Key: PrimaryKey Property . . . . . . . . . . . . . . . . . . . 116
Dynamically Constructing a DataTable. . . . . . . . . . . . . . . . . . . . . . . . 116
DataTable Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
Practical Usage of DataTable Events . . . . . . . . . . . . . . . . . . . . . . . . . 121
Relational Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
The Relations Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Putting It All Together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
DataSets As Data Transfer Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
Strongly Typed DataSets: An Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Overview of XSD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
DataSet Schemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Building Strongly Typed DataSets . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
Typed DataSet Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168

Annotating Typed DataSets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174

■CHAPTER 7

Fetching Data: The DataAdapter . . . . . . . . . . . . . . . . . . . . . . . . . . 177
What Is a DataAdapter? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
Structure of a DataAdapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
Putting DataAdapters to Use . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Setting Up the Data Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Querying One Table: Point and Click . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Querying One Table: Writing Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Filling DataSets: More Than One Table . . . . . . . . . . . . . . . . . . . . . . . . 190
Querying Database Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196

ix


5122chFM.qxd

x

8/23/05

3:44 PM

Page x

■CONTENTS


Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
Using the SQL AS Keyword. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
The ADO.NET Mapping Mechanism . . . . . . . . . . . . . . . . . . . . . . . . . . 206
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212

■CHAPTER 8

Sorting, Searching, and Filtering. . . . . . . . . . . . . . . . . . . . . . . . . . 213
Setting Up the Data Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
Working in a DataTable. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
Finding a Row . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Selecting a Number of Rows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
Expressions: Calculating Columns on the Fly . . . . . . . . . . . . . . . . . . 222
Performing Aggregate Calculations . . . . . . . . . . . . . . . . . . . . . . . . . . 224
Working with the DataRelation Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
Working with the DataView Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
Creating a DataView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
Leveraging XML to Work with Disconnected Data . . . . . . . . . . . . . . . . . . . 240
XmlDataDocument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245

■CHAPTER 9

Updating Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Updating a Table: The Easy Drag-and-Drop Approach . . . . . . . . . . . . . . . 248
How Does It All Work? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
Using the Command Builder Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
State Management in a DataRow and Its Use in Updating Data . . . . . . . 266
Moving Large Amounts of Data: SqlBulkCopy . . . . . . . . . . . . . . . . . . . . . . 276
Editing Disconnected Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278

Add New Rows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
Modify Existing Rows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
Delete Existing Rows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
A Real-World Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
Writing This Application in Oracle . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
Optimizing Your Application: GetChanges and Merge . . . . . . . . . . . . . . . . 294
Merge Case 1: Same Table Structures, No Primary Key . . . . . . . . . 302
Merge Case 2: Same Table Structures, with Primary Key . . . . . . . . 303
Merge Case 3: Common Column, No Primary Key . . . . . . . . . . . . . . 305
Merge Case 4: Common Column, with Primary Key . . . . . . . . . . . . 306
Merge Case 5: Absolutely Different Table Structures. . . . . . . . . . . . 308
Merging Two DataSets/DataTables with Different Schemas . . . . . 310
Updating Records Using Mapped Names . . . . . . . . . . . . . . . . . . . . . . . . . . 311


5122chFM.qxd

8/23/05

3:44 PM

Page xi

■CONTENTS

■CHAPTER 10 Updating Data: Advanced Scenarios . . . . . . . . . . . . . . . . . . . . . . 321
Conflict Detection and Concurrency Resolution . . . . . . . . . . . . . . . . . . . . . 322
Preventing Conflicts: Traffic Lights . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
Handling Conflicts: Going to the Hospital After an Accident . . . . . . 323
Implementing Concurrency: Practical Concerns . . . . . . . . . . . . . . . . . . . . 331

Null Values. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
Number of Rows Affected and Triggers . . . . . . . . . . . . . . . . . . . . . . . 332
Multiple Rows Being Updated . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
Working with Hierarchical Data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
Inserting Hierarchical Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
Updating Hierarchical Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Deleting Hierarchical Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Putting It All Together: Saving Hierarchical Data . . . . . . . . . . . . . . . 347
This Code Just Won’t Work! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
Hierarchical Updates: Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352

■CHAPTER 11 Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
What Is a Transaction? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
ACID Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
Database Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
Transaction Vocabulary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
ADO.NET Transaction Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
Transaction Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
Writing Transactional Database Applications . . . . . . . . . . . . . . . . . . . . . . . 363
Implementing Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
Examining the Effect of Isolation Levels . . . . . . . . . . . . . . . . . . . . . . 370
Multiple Active Resultsets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
MARS and Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382
Advanced Single Database Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
Savepoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
Nested Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
Using Transactions with a DataSet and Data Adapter . . . . . . . . . . . 389
Distributed Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392
Important Players in Distributed Transactions:

RMs and DTCs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392
Two-Phase Commits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
Implementing a Distributed Transaction: The .NET 1.1 Way . . . . . . 393
Implementing a Distributed Transaction: The .NET 2.0 Way . . . . . . 397

xi


5122chFM.qxd

xii

8/23/05

3:44 PM

Page xii

■CONTENTS

Promotable Enlistment: A Quick Primer . . . . . . . . . . . . . . . . . . . . . . . 401
System.Transactions: Manually Enlisting and
Multithreaded Environments. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403
Judicious Use of Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
Transactions and Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409
Default Behavior for Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
Transactions and User Confirmation . . . . . . . . . . . . . . . . . . . . . . . . . . 410
Simultaneous ADO.NET and RDBMS Transactions . . . . . . . . . . . . . . 410
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411


■CHAPTER 12 XML and ADO.NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
SQL Server Native XML Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
FOR XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
FOR XML Queries: A Quick Overview . . . . . . . . . . . . . . . . . . . . . . . . . 415
FOR XML’s Optional Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
FOR XML RAW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
FOR XML AUTO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
FOR XML EXPLICIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
SQL Server 2005 and FOR XML PATH . . . . . . . . . . . . . . . . . . . . . . . . 433
Using FOR XML Queries with ADO.NET . . . . . . . . . . . . . . . . . . . . . . . 434
OPENXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
OPENXML Stored Procedures: Deletes and Updates . . . . . . . . . . . . 440
The XML Data Type: SQL Server 2005 Only . . . . . . . . . . . . . . . . . . . . . . . . 443
Reading XML Columns in ADO.NET . . . . . . . . . . . . . . . . . . . . . . . . . . 444
Working with SQL Server XML Features: SQLXML . . . . . . . . . . . . . . . . . . 446
SQLXML and ADO.NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
The SQLXML Object Model. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459

■CHAPTER 13 The CLR in SQL Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461
Appropriate Use of SQLCLR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
SQLCLR in Comparison with Extended Stored Procedures . . . . . . 464
Software Requirements to Run the Examples in This Chapter . . . . . . . . 465
Handwritten UDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
SQL Server Project UDF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468
Debugging SQLCLR Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472
Writing a TVF: Table-Valued Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
Enumerating Files in a Directory Using a TVF . . . . . . . . . . . . . . . . . . 485
Creating Aggregate Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487



5122chFM.qxd

8/23/05

3:44 PM

Page xiii

■CONTENTS

Writing a SQLCLR Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494
The Context Connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494
SqlTransaction in SQLCLR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504
Using Transactions in SQLCLR Triggers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504
Using Non-Context Connections Inside SQLCLR . . . . . . . . . . . . . . . . . . . . 508
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511

■CHAPTER 14 ADO.NET Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513
Know Your System Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513
Picking the Right Tool for the Right Job . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514
Data Reader or DataSet/Data Adapter? . . . . . . . . . . . . . . . . . . . . . . . 515
DataSet or Strongly Typed DataSets . . . . . . . . . . . . . . . . . . . . . . . . . . 517
Strongly Typed or Not? DataSet vs. Business Object . . . . . . . . . . . . 517
T-SQL vs. SQLCLR vs. Extended Stored Procedures (XP) . . . . . . . . 520
Transactions, Transactions Everywhere: Which Transaction
to Pick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521
Picking the Right Tools: The Clearly Darker Shades of Gray . . . . . . . . . . 522
Implementing a Data Layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523
Closing Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523

Network Latency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524
Complicated Hierarchical DataSets . . . . . . . . . . . . . . . . . . . . . . . . . . 525
Caching Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526

■INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529

xiii


5122chFM.qxd

8/23/05

3:44 PM

Page xiv


5122chFM.qxd

8/23/05

3:44 PM

Page xv

About the Author
■SAHIL MALIK has been working as a consultant in Microsoft technology
for about nine years now. He has worked for many top-notch clients across

the globe, including many Fortune 100 companies and government
organizations within the United States. Sahil started programming in
a DOS world, moved to Win32 API, Borland C, MFC, VC /ATL, Visual
Basic 6, and eventually to .NET in both Visual Basic .NET and C# worlds.
Sahil leads the office of Emerging Technologies at the National
Cancer Institute, and is also currently helping architect a highly visible
public website using ASP.NET 2.0/SQL Server 2005. He speaks frequently
at local user groups and conferences. He was the lead author on
Pro ADO.NET with VB.NET 1.1. For his community involvement and contribution, he has also
been awarded the Microsoft MVP award.

xv


5122chFM.qxd

8/23/05

3:44 PM

Page xvi


5122chFM.qxd

8/23/05

3:44 PM

Page xvii


About the Technical Reviewers
■FRANS BOUMA started programming in 1986 on a Toshiba MSX-1, at the
age of 16. After graduating with a bachelor’s degree in Computer Science
from the Hogeschool Enschede in the Netherlands in 1994, he started
working with 4GL systems and post-relational databases, like uniVerse.
In 1996, he founded Solutions Design, a company for database-driven
web-application development. As the lead developer, he developed
medium to large enterprise web applications using SQL Server, AS400,
COM+, VC++, Visual Basic, and ASP.
In 2001, Solutions Design produced a content-management system completely based on
Microsoft technologies like SQL Server 2000, COM+, VC++, Visual Basic 6, and ASP. The following
year, Frans developed in C# his first .NET application, the open-source LLBLGen code generator
for SQL Server stored procedures and .NET classes. Due to the worldwide success of LLBLGen,
in 2003, Frans designed and developed for Solutions Design the O/R mapper and code generator LLBLGen Pro, which is currently one of the market-leading data-access solutions for .NET,
C#, and VB.NET.
He now works full-time on LLBLGen Pro enhancements. For his community efforts, Frans
received the MVP award for C# in 2004 and 2005.

■ERICK SGARBI was introduced to the computing world in 1981, learned
how to program Sinclair Basic on a ZX Spectrum, and by 1987 became
a full-time AS400 COBOL programmer. He spent 1993 to 2001 working
on several projects, mostly Java, C++, Visual Basic, and Delphi.
Erick attained a bachelor’s degree in Information Systems from
Australia Catholic University and acquired MCAD Charter membership
in 2003. Since 2002, he has been involved in several senior development
positions for .NET projects related to system’s development and supplying contracts for Smart Clients and ASP.NET applications. Over the past few years, Erick has
authored and performed technical reviews and edits on several .NET book titles.

xvii



5122chFM.qxd

8/23/05

3:44 PM

Page xviii


5122chFM.qxd

8/23/05

3:44 PM

Page xix

Acknowledgments
N

o man is an island, and neither are his thoughts. I am merely the medium who wrote
what I heard, read, and learned from various other well-accomplished individuals in my field
or otherwise.
I would first like to thank my countless peers such as Bill Vaughn, Bill Ryan, Miha,
Herfried Wagner, Jon Skeet, Carl Franklin, and countless other superb individuals who spend
their time and effort disseminating what they know. They truly believe that a candle lighting
another candle only creates more light. It is from their endless, tireless discussions, and countless, neverending community interaction that I was able to collect what I present in this book.
None of these ideas is mine: I certainly didn’t invent ADO.NET—I merely learned it from all

these fine people.
I would then like to thank the two most critical, spit-in-the-face reviewers I could find.
I was amazed at the thoroughness Frans Bouma and Erick Sgarbi exhibited in their work.
They pored through the text and, thankfully, did not mince their words in helping solidify the
content of this book. I’d like to thank them both, both as my reviewers and my well-meaning
friends who have always wished the very best for me.
I would then like to thank the various Microsoft employees who graciously agreed to help
with my neverending questions. I sit back and think why they agreed to help a complete stranger,
thousands of miles away—and I cannot come up with a good explanation. These guys replied to
e-mails that I sent at 3 a.m., within a matter of minutes. It is guys like these who truly love what
they do and who are able to make such a fantastic programming platform. Of notable mention are
Pablo Castro, Angel Saenz Badillos, Sushil Chordia, Andy Conrad, Mike Clark, Jim Johnson, Raphael
Renous, Mark Ashton, Michael Rys, Chris Lee, Steve Lasker, and, of course, my MVP Lead Rafael
Munoz. (And yet I think I must have missed a few names).
I would then like to thank my boss at work, who encouraged me and guided me much like
a father would guide his son. I would like to thank Michael Arluk, who lent me his neverending
support and encouragement in this rather difficult and time-consuming task of writing an entire
book in such an aggressive duration and timeline. I have told him, and I will tell you, this book
would not have been possible if it weren’t for him.
Finally, I would then like to thank my parents for being the strictest and most loving parents one can pray for. They taught me discipline, they taught me dedication, they taught me
focus, and they taught me endurance and constancy in tough times.
—Sahil Malik

xix


5122chFM.qxd

8/23/05


3:44 PM

Page xx


5122chFM.qxd

8/23/05

3:44 PM

Page xxi

Introduction
...M

ission control to reader . . . you are now nearing the ADO.NET planet in the .NET
solar system of the Microsoft technology galaxy. Make sure no architectural mistake alien eats
you up for dinner . . .
Learning any new topic is like approaching a new planet. As you approach the planet
from a distance, you first identify its place in the solar system, then the major geographical
features on the surface, and finally you land on it and start digging deep and constructing
buildings to finally call it your home. Then one day before you know it, you are married to
a Mrs. Alien, have two kids, a mortgage, a car payment, and find yourself worrying about
your kid’s college education fund.
It is true!! Life is like a computer game, it keeps getting harder and then you die.
So why should learning ADO.NET be any different? Doesn’t it make sense to start at the
basics and then graduate to the complex?
This book begins with three rather short (about 50 pages combined) and simple chapters:
• The first chapter identifies where ADO.NET is located in the .NET solar system and its

various major building blocks.
• The second chapter begins with identifying the major geographical features of the
ADO.NET terrain. It serves very well as a map for the future chapters when you are on
the ground digging deeper. Because this chapter is a map, you will be reminded to reference back to the various figures, class names, and namespaces presented in this
chapter as you dig deeper in the terrain.
• The third chapter is when you land on the planet and start walking around and create
four data-driven applications of increasing complexity.
Once you have landed on the planet, are armed with a map of the area, and have walked
around a bit is when it’s time to start digging deeper and do what we humans do so naturally—
exploring (without exploding hopefully).
So let me ask you a question, When you hold a tool such as a hammer in your hand, what
do you do with it? You bang things such as a nail with great force on its head, right?
Now what if someone started telling you, here is a hammer, it has two parts—the head
and the handle. The handle is long and thus helps you exert torque because torque is directly
proportional to the radius of the torque arm. The torque translates to a lot of momentum in
a rather heavy hammer head. Now because momentum can neither be destroyed nor created
per the equation
M1V1 = M2V2
and because the mass of the nail is so little, the momentum gets transferred to the nail, which
results in a very high nail velocity thus driving it through the wood.
xxi


5122chFM.qxd

xxii

8/23/05

3:44 PM


Page xxii

■INTRODUCTION

Oh my, I feel like hitting myself with the hammer when I hear such a complex description
of a rather simple topic. Why can’t we just say, “The hammer bangs the nail on its head so it is
driven through the wood”? Simple, huh?
Then why can’t learning ADO.NET be made as simple as that? There are some very basic
things this data access architecture lets you do: connect with the database, fetch data, hold
disconnected data, work with disconnected data, and save data back into the database. In
writing this book, I have therefore tried to focus on the tasks you need to achieve and have
tried to simplify ADO.NET’s architecture in those terms.
Then there is the battle between C# and VB.NET, and different databases such as SQL
Server and Oracle. Choosing between C# and VB.NET is a bit like choosing between democrats
and republicans. No matter which side I pick, I lose half my friends, and it’s not like either
side is any better than the other. So I figured, why choose between these? All examples are
presented both in C# and VB.NET. The examples written will work on a SQL Server 2005
database, but notable differences along with code snippets are presented for Oracle as well.
A good example is MARS. It works both in SQL Server and Oracle, but what are the different
implementation patterns? I will, however, say that, in a bid to prevent this book from looking
like a soup of leftovers from the past week, I have tried to avoid the mish-mash effect by trying to concentrate more on SQL Server than on Oracle—though Oracle has not been ignored.
Thus, Chapters 4 through 11 are filled with content that is database agnostic. They are laid
out in a simple task-oriented approach, which means instead of giving you a rote list of methods on DbCommand, in contrast I take the approach of “You may need to query for a scalar, or
a row, or maybe fill a DataSet instead, and this is how you would do that.”
I could end the book there, but an ADO.NET book wouldn’t be complete if I didn’t mention
SQL Server 2005–specific features such as SQLCLR (the CLR inside SQL Server) and XML features.
Thus, Chapter 12 and Chapter 13 are specific to SQL Server 2005 and cover those topics.
Finally, architecture (especially data access) is a black art. There is no white or black, but
plenty of gray. Okay, certain shades are definitely whiter than others, but you get the idea. The

book ends with a discussion-oriented chapter that brings up the major debates that surround
data access and application architecture in general.
I hope this book will arm you with enough knowledge to allow you to make informed dayto-day architectural decisions with confidence.
I hope you enjoy it.
. . . Mission control to reader . . . the ADO.NET planet is in sight, grab the steering, sit firm in
the pilot’s seat, tighten your seatbelts, pack your bags, and flip over to Chapter 1. The fun is
about to begin . . .


5122ch01.qxd

8/23/05

12:52 PM

CHAPTER

Page 1

1

■■■

An Introduction to ADO.NET
A

computer can be thought of as an information storage and processing machine. While not
every application has a specialized program managing its store of information, it’s hard to imagine a computer program that doesn’t work with any kind of data. Certain applications, like
Microsoft Word and Notepad, choose to manage their own data, while many other specialized
applications, especially those that require vast amounts of data, choose a much more specialized program or architecture that runs on a separate machine, typically referred to as a database.

While some applications choose to use a server-based database architecture, like Oracle,
Microsoft SQL Server, MySQL, DB2, and others, certain other applications might choose a filebased architecture instead, such as Microsoft Access or Excel.
Even various programs on a computer allow you to manage information effectively: programs that are designed specifically to handle information, such as databases that handle
information quite differently than programs that sit between the user and the database. Most
databases store their information as tables, which arrange data as a collection of rows and
columns and values within them. Most modern databases will also let you specify relationships
between these tables, which allow the database to keep data sanctity between various tables
that have relationships between them.
However, programming languages have a different method of representing data. In particular, most modern-day object-oriented languages choose to represent data in hierarchical
representations of objects.
In fact, one program could work with more than one data source at a time and it needs some
sort of data access libraries to accomplish this task, as shown in Figure 1-1.

1


5122ch01.qxd

2

8/23/05

12:52 PM

Page 2

CHAPTER 1 ■ AN INTRODUCTION TO ADO.NET

Figure 1-1. A typical program and its data sources


Therefore, there is a mismatch between how most databases handle information and how
most programming languages handle information. It’s at this very place where ADO.NET fits
into the grand scheme of things.
But what is ADO.NET?

What Is ADO.NET?
Microsoft ADO.NET is part of the Microsoft .NET Framework: a set of tools and layers that
allows your application to easily manage and communicate with its file-based or server-based
data store. In the .NET Framework, the ADO.NET libraries appear under the System.Data namespace. These libraries include functionality to connect to these data sources, execute commands,
and store, manipulate, and retrieve data. This is illustrated in Figure 1-2. For the sake of simplicity
and discussion, only one data source is illustrated, but keep in mind that there could be more
than one.

Figure 1-2. What is ADO.NET and where does it fit in the picture?


Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×