Show/Hide Toolbars

TMS Aurelius Documentation

Navigation: Queries > Retrieving Results

Fetching Objects Using Cursor

Scroll Prev Top Next More

Alternatively to retrieve an object list, you can get results by using a cursor. With this approach, Aurelius executes a query in the database and returns a cursor for you to fetch objects on demand. In this case, the query will remain open until you destroy the cursor. While this approach has the advantage to keeping a database connection alive, it takes advantage of fetch-on-demand features of the underlying component set you are using, allowing you to get initial results without having to fetch all the objects returned. You don't even need to fetch all results, you can close the cursor before it. Cursor can also be used in TAureliusDataset to make it more responsive to visual controls like DB Grids.


To obtain a cursor, use the Open method:



  MyCriteria: TCriteria<TCustomer>;

  Cursor: ICriteriaCursor<TCustomer>;

  FetchedCustomer: TCustomer;


  MyCriteria := ObjectManager1.Find<TCustomer>;

  // <snip> Build the query

  // Retrieve results

  Cursor := MyCriteria.Open;

  while Cursor.Next do


    FetchedCustomer := Cursor.Get;

    // Do something with FetchedCustomer


  // No need to destroy cursor


The Open method returns an ICriteriaCursor (or ICriteriaCursor<T>) interface which is destroyed automatically by reference counting. The underlying

TCriteria object (MyCriteria variable in the example above) is automatically destroyed when cursor is destroyed. Since ICriteriaCursor<T> implements GetEnumerator you can also iterate through the returned entities directly:


  FetchedCustomer: TCustomer;
  for FetchedCustomer in ObjectManager1.Find<TCustomer>.Open do
    // Do something with FetchedCustomer


The ICriteriaCursor and ICriteriaCursor<T> interfaces are declared as following.


  ICriteriaCursor = interface
    function Next: boolean;
    function Fetch: TObject;
    function BaseClass: TClass;
    function ResultClass: TClass;
  ICriteriaCursor<T: class> = interface(ICriteriaCursor)
    function Get: T;
    function GetEnumerator: TEnumerator<T>;


Next method increases cursor position. If result is true, then the new position is valid and there is an object to fetch. If result is false, there are no more objects to be fetched, and cursor must be destroyed. It's important to note that when the cursor is open, it remains in an undefined position. You must call Next method first, before fetching any object. If the very Next call returns false, it means the cursor has no records.


Fetch method is used to retrieve the object in the current cursor position. If Next was never called, or if the result of last Next call was false, Fetch will return unpredictable values. Never call Fetch in such situation.


Get<T> method is just a strong-typed version of Fetch method.


BaseClass method returns the base class used in the criteria query. In the example above, base class would be TCustomer.


ResultClass method returns the class of the returned objects. Usually it's the same as BaseClass, unless in specific cases like when you are using projections, for example. In this case ResultClass will be TCriteriaResult.