Objects and Collections

<< Click to Display Table of Contents >>

Navigation:  Getting Started >

Objects and Collections

Previous pageReturn to chapter overviewNext page

Description

Objects

There are a lot of different ADO object types. Xs2Ado has classes for all the object types included in the ADO and ADOX object models.

 

Collections

Most of the ADO object types have a corresponding collection. A collection includes all the existing objects of that type. For example, the Fields collection contains all open Fields for a given Recordset objects. Each collection is "owned" by another object at the next higher level in the hierarchy. An AdoRecordSet object "owns" a Fields collection. A lot of the objects also have a Properties collection.

 

Each collection is a dynamic list of objects of the same type. The Errors collection consists of one or more Error objects, and the Parameters collection consists of one or more Parameter objects. The Count property of the collection returns the number of elements in a collection.

 

You can reference objects in a collection by using the item property and specifying a symbol, name or a number. When you reference an object (in Visual basic or Visual C++) by number, you should know that the first element in a Collection is always element 0, and the last element is Collection:count-1.

 

This is not the way we are used to work with arrays in Visual Objects, and therefore very confusing. Xs2Ado translates this automatically for you, so you reference the first element as element 1

 

Translating VB syntax to X#

Very often you see a Visual Basic sample that looks like this:

 

  oRecordSet.Fields.Item(0)

  oRecordSet.Fields.Item("Name")

 

Visual Basic also knows something that is called a default property, and Item is the default property of Collections, so this code is often simplified as:

 

  oRecordSet.Fields(0)

  oRecordSet.Fields("Name")

 

X# doesn't support the default property so we can't omit the Item in X#

Further, Visual basic also has a so-called Default Collection, and in this sample the Fields collection itself is the default collection for the RecordSet, so you can omit those in Visual Basic as well:

 

  oRecordSet(0)

  oRecordSet("Name")

 

All of these syntax forms are identical. In Visual Objects in general we don't know these default properties, so we would have to write it like this:

 

  oRecordSet:Fields:Item[0]

  oRecordSet:Fields:Item["Name"]

  oRecordSet:Fields:Item[#Name]

  

Since Xs2Ado automatically translates the Zero-based items to 1 based, the final Xs2Ado syntax for the first line is:

 

 oRecordSet:Fields:Item[1]

 

Finally...:

When you have declared your object properly, X# is smart enough to also understand the following syntax as well:

 

  LOCAL oRecordSet AS AdoRecordSet.

  .

  .

  oRecordset:Fields[1]

 

The X# Compiler is smart enough to know that Fields is an object, and that it makes no sense to use array logic to access elements in an object. So it checks and finds the Item access on the Fields Collection, and inserts that for us.

 

Please note that the following would not work, because the compiler doesn't know how to check for the item access on the Fields class:

 

  LOCAL oRecordSet AS OBJECT // or Usual

  .

  .

  oRecordset:Fields[1]

 

Processing every object in a collection

 

When you need to process every object in a collection you could write a loop and ask for every item like this:

 

  nItems := oCollection:Count

  FOR i := 1 TO nItems

          oItem := oCollection:Item[i]

          // do what you have to do

          Qout(oItem:Name)

  NEXT

 

This works, but is not very efficient. Every time you query for an item, it has to be looked up in the collection.

We have created 2 alternatives in Xs2Ado:

If you want all the objects of a collection, we have created the AsArray() method that transforms the ADO Collection into a X# array, so you can access the elements at full X# speed:

 

  aItems := oCollection:AsArray()

  FOR i := 1 TO aLen(aItems)

          oItem := aItems[i]

          // do what you have to do

          Qout(oItem:Name)

  NEXT

// or

  Aeval(aItems, |oItem| Qout(oItem:Name))

 

Please note that when the collection is large a reference to all objects will be stored in the X# array. This might be too much if you just want to check them one by one.

If you don't want to store all the item objects in an array for later use, we have created even a better way, which is very similar to the For Each construct that is available in Visual Basic, called the ForEach() method. This method accepts a codeblock as a parameter, and that codeblock gets called for every object in the collection. The codeblock receives the object as a parameter. If the codeblock returns a logical False the loop through the collection is aborted. The return value of the method is the number of times the codeblock has been called:

 

  oCollection:ForEach(|oItem|Qout(oItem:Name))

 

Object Caching

If you have to access the elements of a collection by number, we have implemented a caching mechanism in the collection class so the second time you access the same object in the collection, you get it really fast.

 

See Also

AdoCollection, AdoCollectionBase()