The System.Data namespace represents the core of ADO.NET. It contains the fundamental data container classes such as DataSet . Every DataSet contains a collection of DataTable instances. Each DataTable holds a collection of DataRow objects, each of which contains the data for a single row. These data classes are independent of any ADO.NET provider. They simply store disconnected data. In addition, the DataSet also contains objects that describe structural information about your data. This structural information, which is also known as metadata, includes column-specific settings such as data type (found in DataColumn ), foreign key and unique column constraints (represented by ForeignKeyConstraint and UniqueConstraint ), and relations that link columns in different tables (represented by DataRelation ).
Taken together, these objects act like an in-memory relational database, complete with versioning, column and table information, XML output, and automatic enforcement of identity and relational integrity rules. However, these classes are only part of the System.Data namespace. You'll also find the interfaces that must be implemented by every ADO.NET provider. These interfaces define connections (IDbConnection ), commands (IDbCommand ), data readers (IDataReader ), parameters (IDbDataParameter ), transactions (IDbTransaction ), and data adapters (IDbDataAdapter and IDataAdapter ). These interfaces aren't just a low-level part of ADO.NET. You'll need to use them if you want to write generic provider-agnostic data code (as described in Chapter 2). You'll also need to use them to create your own custom provider.
Figure 34-1 shows many of the types in this namespace. Figure 34-2 highlights the exceptions, delegates, and event arguments. See Figure 34-3 for components and other types.