Programming Microsoft ASP.NET 4 - Dino Esposito [218]
ADO.NET Classes
ADO.NET provides a bunch of data container classes that can be filled with any sort of data, including results of a database query. These classes represent excellent resources for filling data-bound controls such as lists and grids. Having memory-based classes such as the DataSet in the list is probably no surprise, but it’s good to find data readers there too. An open data reader can be passed to the data-binding engine of a control. The control will then walk its way through the reader and populate the user interface while keeping the connection to the database busy.
Note
Data binding works differently for Web pages and desktop applications (whether they are Windows Forms or Windows Presentation Foundation applications). The biggest difference is that in Web pages you must explicitly start the data binding process by calling the method DataBind on the page or control class. In desktop solutions, the simple assignment of data to a bindable property triggers the binding process for the specific component.
The DataSet class can contain more than one table; however, only one table at a time can be associated with standard ASP.NET data-bound controls. If you bind the control to a DataSet, you then need to set an additional property to select a particular table within the DataSet. Be aware that this limitation is not attributable to ASP.NET as a platform; it is a result of the implementation of the various data-bound controls. In fact, you could write a custom control that accepts a DataSet as its sole data-binding parameter.
DataSet and DataTable act as data sources through the IListSource interface; DataView and data readers, on the other hand, implement IEnumerable directly.
Queryable Objects
Short for Language INtegrated Query, LINQ is a query language that applies a SQL-like syntax to enumerable collections of data. The typical result of a LINQ query is a queryable object that you can see as an abstraction for a command to execute that will actually get you the data. The peculiarity of queryable objects is that you can bind them to controls regardless of whether data has been retrieved or not.
A queryable object implements the IQueryable interface which, in turn, derives from IEnumerable. The actual object you get from a LINQ query, though, implements this interface in a lazy way such that any attempt to read from the object during data binding will actually execute the query against whatever data store you queried—an in-memory collection, XML file, DataSet, or perhaps SQL Server table. Here’s an example:
// This is a query, defined but not executed yet. The returned
// variable is of a type that implements IQueryable.
var query = from c in customers
where c.Country == "USA"
select c;
// Assignment works because IQueryable derives from IEnumerable.
// As soon as data binding is triggered, an attempt to read from the
// results of the query is made, which will ultimately perform the query.
boundServerControl1.DataSource = query;
A simple attempt to enumerate the elements in the query result set is sufficient to trigger the data fetch operation.
Note
More information on LINQ can be found starting at the following page: http://msdn.microsoft.com/en-us/library/bb397926.aspx.
Data-Binding Properties
All data-bound controls implement the DataSource and DataSourceID properties, plus a few more. The full class diagram for data binding in ASP.NET is detailed in Figure 10-1.
Figure 10-1. Class diagram for data binding in ASP.NET.
As you can see, there are two base classes and subsequently two main subtrees—one rooted in BaseDataList and one rooted in BaseDataBoundControl. The diagram doesn’t extend in a uniform manner and clearly denotes that the various controls have been added at different times. You see this clearly from the distribution of the same set of fundamental properties in the controls derived from BaseDataList and