9.3.2 提取数据
重写PerformSelect方法,就可以提取数据。在提取数据之前,应检查IsBoundUsingData SourceId属性是否设置为True,这表示控件已绑定到DataSourceId属性指定的数据上。如果该属性没有设置为True,就应调用OnDataBinding方法,如下面的Visual Basic 2005示例所示(在这个例子开头声明的对象将在本节后面使用)。
Protected Overrides Sub PerformSelect()
Dim dsa As System.Web.UI.DataSourceSelectArguments
Dim dsv As System.Web.UI.DataSourceView
If Me.IsBoundUsingDataSourceID = False Then
Me.OnDataBinding(EventArgs.Empty)
End If
C#的对应代码如下所示。
protected override void PerformSelect()
{
System.Web.UI.DataSourceSelectArguments dsa;
System.Web.UI.DataSourceView dsv;
if(this.IsBoundUsingDataSourceID == false)
{
this.OnDataBinding(EventArgs.Empty);
}
接着,调用DataSourceView的Select方法(DataSourceView对象可以通过Databound类的GetData方法获得)。Select方法异步提取数据,允许在提取数据的同时继续进行其他处理。Select方法需要以下两个参数。
● DataSourceSelectArguments对象,它允许修改在数据源中指定的数据提取设置。如果不希望设置特别的参数,可以传送CreateDataSourceSelectArguments方法返回的默认对象。
● 提取所有数据后调用的例程(回调例程)。这个例程可以在数据上进行任意处理,再调用例程,把数据移动到页面上。
有两个DataSourceSelectArguments属性可用于大多数情形。
● MaximumRows:设置要提取的最大行数。
● SortExpression:把这个属性设置为该字符串,传送给实际提取数据的DataSource对象,由DataSource对象用于给数据排序。我们应确保该字符串与DataSource兼容。
如果要支持给数据分页,可使用下面三个属性。
● RetrieveTotalRowCount:设置为True时,DataSource会返回要提取的行数。
● TotalRowCount:如果RetrieveTotalRow设置为true,这个属性在处理完成后设置为DataSource可以提取的总行数。这个行数不受MaximumRows设置的影响。例如,如果DataSource返回100行,而MaximumRows设置为10,则TotalRows设置为100。
● StartRowIndex:要提取的第一个记录的位置。
注意:
并不是所有的数据源都支持所有与数据相关的操作。DataSourceView对象有许多属性,指明数据源可以做些什么,不能做什么。例如,如果数据源可以返回总行数,CanRetrieveTotalRow Count就属性返回True。在设置DataSourceSelectArguments上的属性之前,最好检查DataSourceView对象上的Can*属性。
下面的Visual Basic 2005示例创建了一个DataSourceSelectArguments对象,把最大行数设置为10,请求可提取的总行数(假定数据源支持提取所有的行)。接着,代码调用GetData方法,检索DataSourceView,调用其Select方法。HandleRetrievedData指定为提取数据时调用的回调例程。
dsa = New System.Web.UI.DataSourceSelectArguments
dsa.MaximumRows = 10
dsv = Me.GetData
If dsv.CanRetrieveTotalRowCount = True Then
dsa.RetrieveTotalRowCount = True
End If
dsv.Select(dsa, AddressOf Me.HandleRetrievedData)
C#的对应代码如下所示。
dsa = new System.Web.UI.DataSourceSelectArguments();
dsa.MaximumRows = 10;
dsv = this.GetData();
if (dsv.CanRetrieveTotalRowCount == true) {
dsa.RetrieveTotalRowCount = true;
}
dsv.Select(dsa, this.HandleRetrievedData);
提取了数据后,还要完成三个任务:告诉ASP.NET,不需要再次调用PerformSelect方法了,确保存储数据绑定的状态,让代码在数据绑定完成后执行。完成这些任务有三个机制。
● RequiresDataBinding:把这个属性设置为False,可以禁止ASP.NET第二次调用PerformSelect方法。
● MarkAsDataBound:更新ViewState,表示控件已数据绑定。
● OnDataBound:引发DataBound事件,以执行该事件中的代码。这样,就可以把代码与数据绑定操作关联起来。
下面的Visual Basic 2005代码用于执行这三个任务。
RequiresDataBinding = False
MarkAsDataBound()
OnDataBound(EventArgs.Empty)
C#的对应代码如下所示。
RequiresDataBinding = false;
MarkAsDataBound();
OnDataBound(EventArgs.Empty);
提示:
最好在调用Select事件后立即设置RequiresDataBinding,以禁止再次调用PerformSelect方法。也可以在所有的数据都成功提取,并移动到页面上后,再调用MarkAsDataBound。调用OnDataBound来引发DataBound事件也是这个目的。此时,可以在回调例程中执行这些任务。
在Select方法中指定的回调例程需要一个参数:Select方法提取的数据。在回调例程中,可以执行需要的任何操作,之后显示数据(可以从数据集合中删除项,或对它们执行一些处理)。
在执行完数据处理后,就准备执行这个例程最重要的部分:调用DataBound对象的PerformDataBinding方法。PerformDataBinding方法可以把数据移动到页面上。下面的Visual Basic 2005示例提供了最简单的实现代码。
Private Sub HandleRetrievedData(ByVal data As IEnumerable)
PerformDataBinding(data)
End Sub
C#的对应代码如下所示。
private void HandleRetrievedData(System.Collections.IEnumerable data)
{
PerformDataBinding(data);
}






