ADO.NET is far more than just a managed version of ADO. It represents a different and more scalable way of approaching database access, ideal for use in a data layer that might be supporting hundreds or thousands of users, and yet a way that also works well for a single user application.
ADO.NET hinges around two classes: the DataSet and the DataReader . If you're familiar with XML programming, you can think of these as equivalent to DOM and SAX. The DataSet , like DOM, gathers all the information together into an easily accessible structure and then closes the data source. You can work with the data, shuffle it around, add and remove entries, get some information from the beginning, jump ahead to the end, jump back to the middle, and even put data back to the source when you're finished with it. The DataReader , like SAX, is used to process information as you read it from the source. It's often referred to as one-way-one-way access; you can only go through the data by starting at the beginning and reading to the end (one way) and you can only read information from the source, you can't put updates back into the source (one way).
A DataSet contains a collection of DataTable objects, which can be related to each other through DataRelation objects. Each DataTable contains a collection of DataRow objects, and at the same time a collection of DataColumn objects. What a DataSet does not contain is any information about where the data came from. DataSets don't fill themselves ; instead they are filled by a companion object called a DataAdapter . A DataAdapter holds four commands: one for reading from the database, one for inserting records, one for deleting records, and one for updating information. Generally the latter three commands are not used (if you're not updating the information back to the data source) or are machine-generated from your Select command, the one that reads from the database.
A DataSet can be bound to a variety of controls in a user interface, such as a data grid. You can easily persist it as XML, and it's perfect for passing from layer to layer, even from machine to machine. Although it's by no means a small or light-weight class, it is full of functionality that is needed in almost every data-enabled application.