Freigeben über


My simple approach to pagination in Windows Azure Table Storage

As part of my simple Azure Assets application I first focussed on Pagination. Although my test data was relatively small I knew that there were a number of categories for the data and many types which, if not paginated, could look daunting to the user.

Unfortunately, and probably due to the statelessness of Windows Azure, the typical take and skip methods threw up errors. This meant I needed to understand how I could implement pagination myself. Since my application was a web page I went about reading how in ASP.NET I can efficiently page through large amounts of data. By understanding the custom paging process I was able to link my ASP ListView and bind to a data source. I wanted to use as little code as possible. By using ObjectDataSource I could mirror the StartRowIndexParameterName and MaximumRowsParameterName.

You may also find that you may want to add other parameters in the query like the partition key from your Windows Azure Storage . This is simply achieved by adding other select parameters and changing the

ObjectDataSource1.SelectParameters["PartitionKey"].DefaultValue = value;

By adding a timer I could update the page regularly with any changes.

protected void Timer1_Tick(object sender, EventArgs e) { lv.DataBind(); DataGrid1.DataBind(); }

I then moved to my data classes which I modelled from the Windows Azure Platform Training Course simple Guest Book example in the Building Your First Windows Azure Application.

In this simple example you create a data project which contains a Source, a Context and a Data Entity.

public class AssetDataSource

** – this is the service class for your calling web page

e.g.        public IEnumerable<Asset> GetAssets(string PartitionKey, int MaximumRows, int StartRowIndex)

public AssetDataContext(string baseAddress, Microsoft.WindowsAzure.StorageCredentials credentials)
: base(baseAddress, credentials)

** this is where the query occurs against the storage table

public class Asset : Microsoft.WindowsAzure.StorageClient.TableServiceEntity

** this is a simple data class this inherits behaviours and properties needed for Windows Azure Storage

After reading Scott Densmore on Paging with Windows Azure Table Storage I understood that in recent SDK’s the CloudTableQuery<TElement> handles dealing with continuation tokens. Continuation tokens, I think, are a bit of a shim, to create a storable token the developer can use to store where the last page occurred.

Unfortunately the documentation is a bit scant on how this all works, but thanks to good old patterns and practice (and as highlighted by Eugenio Pace) Scott's efforts have been documented in a sample application which is Implementing Paging with Windows Azure Table Storage. At its core is a small class ContinuationStack you need to implement in your web page. As you move through your data returned from the DataContext query a token returned from the stack is stored in session state.

This was all fine for me except I was using ObjectDataSource and it a synchronous method. For this reason I moved the Continuation stack to my Data Source object which provides the method GetAssets for the ObjectDataSource to bind to.

// start async call
IAsyncResult asyncResult = BeginAsyncOperation(new AsyncCallback(this.EndAsyncOperation));

// because waiting for result then call end result will get result of operation with WaitOne
this.EndAsyncOperation(asyncResult);

When the results are gleaned the following small method is implemented

private void EndAsyncOperation(IAsyncResult result)
{
var cloudTableQuery = result.AsyncState as CloudTableQuery<Asset>;
ResultSegment<Asset> resultSegment = cloudTableQuery.EndExecuteSegmented(result);
this.ContinuationStack.AddToken(resultSegment.ContinuationToken);
this.assets = resultSegment.Results.ToList();
}

If you really want to get more into detail about this I’d recommend these two article for further reading:

Ill be updating this post later with my move to OData which simplifies things a little.