Foggon_577-7FRONT.fm Page i Sunday, February 26, 2006 7:27 AM Beginning ASP.NET 2.0 Databases From Novice to Professional ■ ■ ■ Damien Foggon Foggon_577-7FRONT.fm Page ii Sunday, February 26, 2006 7:27 AM Beginning ASP.NET 2.0 Databases: From Novice to Professional Copyright © 2006 by Damien Foggon 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-59059-577-0 ISBN-10 (pbk): 1-59059-577-7 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: Ronald Landers, Sahil Malik Editorial Board: Steve Anglin, Dan Appleman, Ewan Buckingham, Gary Cornell, Jason Gilmore, Jonathan Hassell, James Huddleston, Chris Mills, Matthew Moodie, Dominic Shakeshaft, Jim Sumser, Matt Wade Project Manager: Richard Dal Porto Copy Edit Manager: Nicole LeClerc Copy Editors: Marilyn Smith, Kim Wimpsett Assistant Production Director: Kari Brooks-Copony Production Editor: Kelly Gunther Compositor: Susan Glinert Proofreader: Linda Seifert Indexer: Julie Grady Artist: Kinetic Publishing Services, LLC 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 [email protected], or visit http://www.springeronline.com. 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 [email protected], or visit http://www.apress.com. 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 http://www.apress.com in the Source Code section. Foggon_577-7FRONT.fm Page iii Sunday, February 26, 2006 7:27 AM Contents at a Glance About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xix About the Technical Reviewers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xxi Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xxiii Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxv ■ CHAPTER 1 Data Sources and the Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 ■ CHAPTER 2 Introducing Relational Databases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 ■ CHAPTER 3 Displaying Data on a Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 ■ CHAPTER 4 Database Access in Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 ■ CHAPTER 5 DataReader and DataSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 ■ CHAPTER 6 Inline and List Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 ■ CHAPTER 7 Table Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 ■ CHAPTER 8 Writing to the Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 ■ CHAPTER 9 The GridView Family . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367 ■ CHAPTER 10 Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415 ■ CHAPTER 11 Modifying the Database Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . 459 ■ CHAPTER 12 Useful Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497 ■ CHAPTER 13 Application Design and Implementation . . . . . . . . . . . . . . . . . . . . . . 547 ■ APPENDIX A Installation Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571 ■ APPENDIX B SQL Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 579 ■ APPENDIX C SQL Primer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591 ■ APPENDIX D Sample Database Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597 ■ INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607 iii Foggon_577-7FRONT.fm Page iv Sunday, February 26, 2006 7:27 AM Foggon_577-7FRONT.fm Page v Sunday, February 26, 2006 7:27 AM Contents About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xix About the Technical Reviewers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xxi Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xxiii Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxv ■ CHAPTER 1 Data Sources and the Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Are Data-Driven Web Sites a Good Idea? . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 How Do Web Sites Use Data Sources? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Database Uses in a Web Environment . . . . . . . . . . . . . . . . . . . . . . . . . 4 How Does the Web Site Get the Data?. . . . . . . . . . . . . . . . . . . . . . . . . 6 Looking for Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Database Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Flat Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Web Services. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Services. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Introducing ADO.NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Data Access Technology: A Brief History. . . . . . . . . . . . . . . . . . . . . . 11 Data Providers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Data Source Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 Developing Your First Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 Try It Out: Creating a Simple Data-Driven Page . . . . . . . . . . . . . . . . 19 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 ■ CHAPTER 2 Introducing Relational Databases . . . . . . . . . . . . . . . . . . . . . . . . 27 The Databases and Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Tables, Rows, and Columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Try It Out: Creating a Table in SQL Server 2005. . . . . . . . . . . . . . . . 31 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 Try It Out: Creating a Table in MySQL 5.0 . . . . . . . . . . . . . . . . . . . . . 36 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 Column Properties and Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . 40 v Foggon_577-7FRONT.fm Page vi Sunday, February 26, 2006 7:27 AM vi ■ CONTENTS Queries and Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 SQL Queries. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Indexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Types of Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 Try It Out: Adding Indexes in SQL Server 2005. . . . . . . . . . . . . . . . . 48 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 Try It Out: Adding Indexes in MySQL 5.0. . . . . . . . . . . . . . . . . . . . . . 51 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Relationships Between Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 Types of Relationship. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 Foreign Keys and Foreign Key Constraints . . . . . . . . . . . . . . . . . . . . 56 Try It Out: Adding Relationships in SQL Server 2005. . . . . . . . . . . . 58 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 Try It Out: Adding Relationships in MySQL 5.0 . . . . . . . . . . . . . . . . . 61 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 Database Diagrams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 Try It Out: Creating a Database Diagram in SQL Server 2005. . . . . 64 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Try It Out: Using a Database Diagram to Create a New Relationship in SQL Server 2005. . . . . . . . . . . . . . . . . . . . 66 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 Users, Roles, and Permissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 Try It Out: Creating User Accounts in SQL Server 2005. . . . . . . . . . 69 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 Try It Out: Creating User Accounts in MySQL 5.0. . . . . . . . . . . . . . . 71 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 Data for the Sample Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 Try It Out: Adding Data to a SQL Server 2005 Database . . . . . . . . . 72 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 Try It Out: Adding Data to a MySQL 5.0 Database . . . . . . . . . . . . . . 73 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Database Views and Triggers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Foggon_577-7FRONT.fm Page vii Sunday, February 26, 2006 7:27 AM ■ CONTENTS vii ■ CHAPTER 3 Displaying Data on a Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 Introducing the Data Source Web Controls . . . . . . . . . . . . . . . . . . . . . . . . 78 Introducing SELECT Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Try It Out: Querying a Single Table. . . . . . . . . . . . . . . . . . . . . . . . . . . 79 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 Try It Out: Ordering the Results. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 Try It Out: Querying Multiple Tables. . . . . . . . . . . . . . . . . . . . . . . . . . 94 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 Try It Out: Filtering the Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 Try It Out: Filtering Results and Showing All Results . . . . . . . . . . . 106 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 Introducing the WHERE Clause . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 Using Comparison Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 Using Logical Operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 Using the IN and BETWEEN Operators . . . . . . . . . . . . . . . . . . . . . . . 110 Connecting to MySQL 5.0 and Microsoft Access . . . . . . . . . . . . . . . . . . 111 Connection Strings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 Parameters and Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 ■ CHAPTER 4 Database Access in Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 The Connection and Command Life Cycle . . . . . . . . . . . . . . . . . . . . . . . . 116 Connection Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Try It Out: Connecting to SQL Server 2005 Using SqlConnection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 Try It Out: Connecting to MySQL 5.0 Using OdbcConnection . . . . 121 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 Try It Out: Connecting to Microsoft Access Using OleDbConnection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 Connection Object Methods and Properties. . . . . . . . . . . . . . . . . . . 126 Connection Pooling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 Foggon_577-7FRONT.fm Page viii Sunday, February 26, 2006 7:27 AM viii ■ CONTENTS Command Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 Creating a Command Object. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 Returning the Results. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 Filtering the Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 Try It Out: Modifying the Query. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 Try It Out: Using Parameters in Queries. . . . . . . . . . . . . . . . . . . . . . 138 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 Parameters and Queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 Command Object Methods and Properties . . . . . . . . . . . . . . . . . . . 142 Scalar Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Scalar Functions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 Try It Out: Using the ExecuteScalar() Method . . . . . . . . . . . . . . . . . 144 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 Try It Out: Catching and Handling Errors . . . . . . . . . . . . . . . . . . . . . 147 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 ■ CHAPTER 5 DataReader and DataSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 The DataReader Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 How to Read Through a DataReader . . . . . . . . . . . . . . . . . . . . . . . . 157 Try It Out: Iterating Through a DataReader . . . . . . . . . . . . . . . . . . . 159 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 DataReader Properties and Methods . . . . . . . . . . . . . . . . . . . . . . . . 165 The DataSet Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 How to Fill a DataSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 Try It Out: Iterating Through a DataSet. . . . . . . . . . . . . . . . . . . . . . . 173 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 Creating a DataSet from Scratch . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 SqlDataSource—DataSet or DataReader? . . . . . . . . . . . . . . . . . . . . . . . . 185 DataSet vs. DataReader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 Good Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 Foggon_577-7FRONT.fm Page ix Sunday, February 26, 2006 7:27 AM ■ CONTENTS ix ■ CHAPTER 6 Inline and List Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 Data-Binding Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 Data Binding in Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 Data Binding and the SqlDataSource. . . . . . . . . . . . . . . . . . . . . . . . 191 Data-Aware Web Controls. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 Associating Data to the Web Control . . . . . . . . . . . . . . . . . . . . . . . . 192 Inline Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 Try It Out: Inline Binding to a DataReader . . . . . . . . . . . . . . . . . . . . 195 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 Try It Out: Inline Binding to a DataSet . . . . . . . . . . . . . . . . . . . . . . . 201 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 The Inline Binding Alternative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 Try It Out: Showing Data from a DataReader . . . . . . . . . . . . . . . . . 206 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 Try It Out: Showing Data from a DataSet. . . . . . . . . . . . . . . . . . . . . 208 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 List Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 Try It Out: Using Single-Value Lookup Lists with a DataReader. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 List Binding Events. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 Try It Out: Using Lookup Lists and Events with a DataReader. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 Try It Out: Using Lookup Lists and Events with a DataSet. . . . . . . 225 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228 Try It Out: Using Lookup Lists and Events with a SqlDataSource . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 Connecting to Other Data Sources . . . . . . . . . . . . . . . . . . . . . . . . . . 235 Multiple Selection Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 Try It Out: Using Multiple-Value Lookup Lists with a DataReader. . . . 236 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 Try It Out: Using Multiple-Value Lookup Lists with a SqlDataSource. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242 How It Works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244