The heart of many serious commercial software products is data, stored in a database. If you are going to interact with a database, however, you must match the object-oriented perspective of .NET to the relational perspective of your backend database.
An inherent "impedance-mismatch" between the object-oriented and the relational world has been a problem for object-oriented programmers for many years. Microsoft attempts to overcome this obstacle by offering a complete set of classes for interacting with your database within an object-oriented hierarchy of classes. This set of classes is called ADO.NET.
ADO.NET looks, at first, very similar to ADO, its predecessor technology. The key difference between ADO and ADO.NET is that ADO is built around a recordset, while ADO.NET has as one of its key elements a DataSet that models the entire database, including tables, relationships among tables, and constraints added to interactions to maintain referential integrity. ADO.NET goes beyond the DataSet to include objects that serve as abstractions for the connection to your database, commands, connected fire-hose cursors, and so forth, all of which will be covered in this chapter.
The DataSet represents a disconnected data architecture, which is ideal for Windows (WinForm) applications. A disconnected architecture is database resource-frugal. Connections are used only briefly. Of course, ADO.NET does connect to the database to retrieve data, and connects again to update data when you've made changes. When not updating data to or from the database, the connection is broken. Most applications spend most of their time simply reading through data and displaying it, and ADO.NET provides a disconnected subset of the data for your use while reading and displaying.
As you might imagine, disconnected DataSets can have scale and performance problems of their own. There is overhead in creating and tearing down connections, and if you drop the connection each time you fill the DataSet and then must reestablish it each time you update the data, you will find that performance degrades quickly. This problem is mitigated by the use of connection pooling. While it looks to your application like you are creating and destroying connections, you are actually borrowing and returning connections from a pool that ADO.NET manages on your behalf.