SqlDataSource_OnSelected: 获取数据(DataTable)而不重新执行查询

SqlDataSource_OnSelected: Get data (DataTable) without re-executing the query

我有一个 SqlDataSource 绑定到一个带有 SQL 的 GridView,检索数据大约需要 10 秒。

还有一个名为 "PageSizeControl" 的 UserControl,它挂钩 GridView 的 SqlDataSource 的选定事件。在这种情况下,我需要DataTable来准备PageSizeControl的一些设置。

目前,我正在使用以下代码执行此操作:

protected void ds_Selected(object sender, SqlDataSourceStatusEventArgs e)
{
    SqlDataSourceView dsv = (sender as SqlDataSourceView);
    dsv.Selected -= ds_Selected;
    DataTable dt = (dsv.Select(DataSourceSelectArguments.Empty) as DataView).Table;
    int iRowCount = dt.Rows.Count;

    // some gui-adaption like visibility, text, ...
 }

在旧版本中我们使用 e.AffectedRows。但是当过滤器应用于 DataSource 时,存储在 e.AffectedRows 中的值不正确。我们有一些用例,我们不仅需要行数,还需要整个 DataTable。

问题是,.Select() 重新执行 Db-Query,这又需要 10 秒才能完成。

我还尝试在 SqlDataSource 上启用缓存:

EnableCaching="true" CacheDuration="Infinite"

但这没有帮助,原因有二: 1. 访问缓存数据时不会触发 OnSelected 事件 2. 如果 OnSelected 事件被触发(因为数据尚未缓存),.Select() 仍在未缓存的情况下执行并需要 10 秒。

有没有人知道我如何获取数据而无需耗时地重新执行查询?最好是在 OnSelected 中,但我愿意接受其他建议。

我找到了符合我要求的解决方法 运行。我使用事件 GridView.OnRowDataBound 并获取第一个 GridRow 的 DataItem,其中包含 DataTable。

private DataTable oData = null;
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (oData == null && e.Row.DataItem != null)
    {
        oData = (e.Row.DataItem as DataRowView).Row.Table;
    }
}

此解决方案有效,但它看起来很脏,并且需要 GridView(在我的情况下没问题)。如果有更干净的解决方案,我将不胜感激。

更新 在对 IlSpy 进行更长时间的研究后,我得出的结论是无法在 OnSelected 事件中获取数据。即使启用缓存也不会,因为缓存是在 OnSelected 之后写入的。

所以最简单的方法是打开缓存并在需要数据的地方调用 SqlDataSource.Select(...) 函数。

另一种方法是自己使用SqlDataSource.Select(...) 获取数据,然后将table 绑定到控件。但这有一些缺点。例如:当绑定到 dataset/datatable.

时,GridView 上的排序和分页无法开箱即用

还有一种方法是从选择它的控件中提取数据。请参阅上面的 GridView 示例。