Figures
© 2004 Microsoft Corporation. All rights reserved.
Figure 1 Results of Cache Loading
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.IO" %>

<script runat="server">
void Page_Load(Object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        DataFromSourceToMemory("MyDataSet");
        UpdateDataView();
    }
}

void DataFromSourceToMemory(String strDataSessionName)
{
    // Gets rows from the data source
    DataSet oDS = PhysicalDataRead();
    
    // Stores it in the session cache
    SerializeDataSource(oDS);
}

DataSet PhysicalDataRead()
{
    // Creates connection and command string
    String strConn, strCmd;
    strConn = "DATABASE=Northwind;SERVER=localhost;UID=sa;PWD=;";
    strCmd = "SELECT productid, productname, unitprice, unitsinstock FROM 
       Products";
    
    SqlDataAdapter oCMD = new SqlDataAdapter(strCmd, strConn);
    DataSet oDS = new DataSet();
    oCMD.Fill(oDS, "MyList"); 
    return oDS;
}

void UpdateDataView()
{
    DataSet ds;
    try  { 
        ds = DeserializeDataSource();
    } catch {
        ds = PhysicalDataRead();
    }
    
    DataView dv = ds.Tables["MyList"].DefaultView;

    // Re-bind data 
    grid.DataSource = dv;
    grid.DataBind();
}
Figure 2 global.asax
<%@ Application Language="C#" %>
<%@ Import Namespace="System.IO" %>

<script runat="server">
public void Session_OnStart(Object sender, EventArgs e) 
{ 
}
public void Session_OnEnd(Object sender, EventArgs e) 
{
    String strFile;
    strFile = Server.MapPath(Session.SessionID + ".xml");
    File.Delete(strFile);    
}
</script>
Figure 5 Diffgram
<?xml version="1.0" standalone="yes" ?>
<MyDataSet xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" 
    xmlns:updg="urn:schemas-microsoft-com:xml-updategram">
    <updg:sync>

        <!-- This record has been deleted: <before> but not <after> -->
        <updg:before>
            <Table1 updg:id="9b6ff52f-3fed-46d5-a18b-d36fdd476ca3" 
                xmlns="dinoe-expoware">
                <Field1>...</Field1>
                <Field2>...</Field2>
                <Fieldn>...</Fieldn>
            </Table1>
        </updg:before>
        <updg:after />

        <!-- This record has been modified: both <before> and <after> -->
        <updg:before>
            <Table1 updg:id="1078f0b1-c0e3-4e41-b3c6-cb6390827417" 
                xmlns="dinoe-expoware">
                <Field1>...</Field1>
                <Field2>...</Field2>
                <Field3>...</Field3>
            </Table1>
        </updg:before>
        <updg:after>
            <Table1 updg:id="1078f0b1-c0e3-4e41-b3c6-cb6390827417" 
                xmlns="dinoe-expoware">
                <Field1>...</Field1>
                <Field2>...</Field2>
                <Field3>...</Field3>
            </Table1>
        </updg:after>

        <!-- This record has been added: no <before> but <after> -->
        <updg:before />
        <updg:after>
            <Table1 updg:id="290810d0-1f67-42f9-b2d1-c4c5a03211c1" 
                xmlns="dinoe-expoware">
                <Field1>...</Field1>
                <Field2>...</Field2>
                <Field3>...</Field3>
            </Table1>
        </updg:after>
    </updg:sync>
</MyDataSet>
Figure 6 Custom Pagination and Data Readers
<script runat="server">
public void Page_Load(Object sender, EventArgs e)
{
    // Initialize only the first time...
    if (!Page.IsPostBack)
        SetVirtualItemCount();
}

private void OnLoadData(Object sender, EventArgs e)
{
    grid.DataSource = CreateDataSource(0);
    grid.DataBind();
    dr.Close();
}

private void SetVirtualItemCount()
{    
    // Set up the connection
    String strConn = "DATABASE=Northwind;SERVER=localhost;UID=sa;PWD=;";
    SqlConnection conn = new SqlConnection(strConn);

    // Set up the command
    String strCmd = "SELECT COUNT(*) FROM products";
    SqlCommand cmd = new SqlCommand(strCmd, conn);
    
    // Execute the command
    conn.Open();
    int nItemCount = (int) cmd.ExecuteScalar();
    conn.Close();

    grid.VirtualItemCount = nItemCount;
    return;
}

// Global variable
SqlDataReader dr;

// Used to page through data
private SqlDataReader CreateDataSource(int nPageIndex)
{
    // page index is assumed to be 0-based
    int nPageSize = grid.PageSize;
    int nBaseProductID = nPageSize * nPageIndex;

    // Set up the connection
    String strConn = "DATABASE=Northwind;SERVER=localhost;UID=sa;PWD=;";
    SqlConnection conn = new SqlConnection(strConn);

    // Set up the command to page through data
    String strCmd = "SELECT TOP " + nPageSize + " " +
            "productid, productname, quantityperunit, unitsinstock " + 
            "FROM products " + "WHERE productid >" + nBaseProductID;
    SqlCommand cmd = new SqlCommand(strCmd, conn);
    
    // Execute the command
    conn.Open();
    dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
    return dr;

    // Notice the connection and the reader are NOT closed at this point.
    // The command behavior set only states that the connection will be 
    // automatically shut down upon reader's closing
}

public void PageIndexChanged(Object sender, DataGridPageChangedEventArgs e)
{
    grid.CurrentPageIndex = e.NewPageIndex;
    grid.DataSource = CreateDataSource(grid.CurrentPageIndex);
    grid.DataBind();

    // Explicitly close the reader used within CreateDataSource
    dr.Close();
}
</script>
Page view tracker