Working with the PagedObjectReader

The CTP March 2005 build of ObjectSpaces introduces the PagedObjectReader. This class is derived from the ObjectReader, which you already know from the PDC version. Here’s a short tutorial to get you started with it.

The PagedObjectReader will materialize the objects in consecutive batches of predetermined size. These batches are the pages, from which the class gets its name. The PagedObjectReader works largely the same as the ObjectReader in providing three ways to iterate through the objects:

  1. An IEnumerator interface reference is returned from a call to GetEnumerator.
  2. Read method to materialize the next object and Current property to retrieve it.
  3. A foreach construct (but essentially the same as 1)

It does have some extra properties:

  • CurrentPosition: returns the zero-based position of the current object in the total batch that the reader will return for this particular query.
  • PageSize: size of the individual batches.
  • ReadForcesPageFetch: boolean value that indicates whether a read forces the fetching of a page. Effectively, this means that you will never reach the end of the page, so there is no need to advance to the next page. The default is false.

The extra methods are these:

  • GetCount(): the total number of objects this reader will materialize. It causes a SELECT COUNT(*) query to the server. You might need this total in conjunction with the ReadAt… methods mentioned later.
  • MoveToNextPage() and MoveToPreviousPage(): advances to the next and previous batch respectively. A boolean return value indicates whether this page is available.
  • ReadAtPosition(Int32) and ReadAtPercent(Int32): materializes the object at the specified position or at the percentage relative position of the total. This object is available through the Current property. Alternatively, you can start your iteration over the page that was retrieved as part of this reading. So, when reading at position 123 with a page size of 10, you will iterate through positions 123-132.
  • Reset(): returns the position of the reader/iterator to the first object of the query, not the page.

As an example of how to put it all to use, here is a code fragment. The database is Northwind, of which the Orders table has been mapped to Order class. The code should be selfexplanatory. It also shows the new way to get your ObjectSpace object and perform a query.

Dim space As ObjectSpace
Dim con As SqlConnection
Dim map As ObjectMapping

‘Create a mapping and corresponding connection
map = New ObjectMapping(“..Mapping.msd”)
con =
New SqlConnection(“DATA SOURCE=(local);INITIAL CATALOG=Northwind;INTEGRATED SECURITY=SSPI”)
space =
New ObjectSpace(map, con)

Dim expression AsNew OPathExpression(“OrderID < 10800”)

‘Notice use of Generics for object query
Dim query As ObjectQuery(Of Order)
query =
New
ObjectQuery(Of Order)(expression, “”)

‘Retrieve objects from query in pages of size 10.
Dim reader As PagedObjectReader(Of Order) = _
    space.GetPagedObjectReader(query, 10)
Dim ord As Order

If reader.HasObjects Then

  ‘Advance to middle of range of objects
  reader.ReadAtPercent(50)
  Console.WriteLine(“This will retrieve {0} objects.”, _
      reader.GetCount())

  ‘No casting necessary any more
  ord = reader.Current()
  Console.WriteLine(reader.CurrentPosition & “: ” & ord.OrderID)

  ‘This will iterate through 10 Order objects
  ForEach ord In reader
   
Console.WriteLine(reader.CurrentPosition & “: ” & ord.OrderID)
  Next

  ‘Go to next page and read objects using enumerator
  reader.MoveToNextPage()

  Dim iterator As IEnumerator(Of Order)
  iterator = reader.GetEnumerator()
  DoWhile iterator.MoveNext
    Console.WriteLine(reader.CurrentPosition & “: ” & _
        iterator.Current.OrderID)
  Loop

  ‘Back to object zero and read first 10 objects
  reader.Reset()
  DoWhile reader.Read
    Console.WriteLine(reader.CurrentPosition & “: ” & _
        reader.Current.OrderID)
  Loop

EndIf

As a side note: Using the GetCount() method before a read operation or moving to another page has been performed will give an InvalidOperationException, stating that an open DataReader has already been associated with the command. Not sure why this is.

If you’re interested in the source code, mail me or drop a comment.

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s