Persistate

Collections of several objects

Hide Navigation Pane

Collections of several objects

Previous topic Next topic No directory for this topic  

Collections of several objects

Previous topic Next topic Topic directory requires JavaScript JavaScript is required for the print function Mail us feedback on this topic!  

When you define a collection of several objects, Persistate generates a public collection property to access the member objects, along with a private field to actually hold the objects.  When you access a several collection property for the first time, Persistate retrieves the entire collection from persistent storage and places it in the collection field.  All of the objects are then accessible immediately.

The type of all collections properties in memory is IndexedList<T>.  This is a collection type implementing IList and IList<T>, and as the name suggests, provides indexers allowing you to access objects based on the value of distinctive members.  It is also part of the run time infrastructure which handles the transfer of objects to and from persistent storage.

Future Enhancement

In a future version of Persistate, there will be more types of persistent collection, such as fixed length collections, collections of data classes, and more.

The following example iterates through an author’s books looking for one with the same title as a new book.  When the Books property is accessed in the first line, Persistate will fetch the appropriate Book objects from persistent storage if it has not yet done so, and then return the resulting collection.

foreach (Book book in newBook.Author.Books)
   if (book.Title == newBook.Title)
      return true;

IndexedList<T> provides the standard integer indexer of an IList<T>, as in the following example.

IndexedList<Genre> genres = The.Library.Genres;
for (int i = 0; i < genres.Count; i++)
   if (genres[i].Name == "OldGenre")
      genres.RemoveAt(i);

Indexes on distinctive members

As mentioned above, IndexedList<T> also provides indexers based on the value of distinctive members of the class of its elements.  Given that Name is a distinctive member of Genre, the above example could have been written as in the following example.  Note the string indexer used to retrieve the Genre.  The string indexer always indexes on the value of the first distinctive member of the object class with generated type String.

IndexedList<Genre> genres = The.Library.Genres;
genres.Remove(genres["OldGenre"]);

For distinctive members other than the first string one, you can use a two parameter indexer.  Persistate generates a key constant for each distinctive member for use as the first parameter.  This includes distinctive members of base classes too, as used in the following example.  You supply the key value as the second parameter.  As you can infer from this example, the indexers return null if the index does not contain the key.

foreach (Author author in The.Library.AuthorsWithSurname(suppliedSurname))
   if (author.Books[Book.IsbnNumberKey, suppliedBook.IsbnNumber] != null)
      author.Books.Remove(suppliedBook);

An important facet of these indexes is that if you do not use them, they are not created.  This is true for each individual index on a distinctive member.  The first time you access an index using one of the indexers, it is created at that point.  Once one is created, then it is kept up to date as objects are added and removed from the collection.

Caution

If you alter the value of a distinctive member of an object in the collection, then the index for that distinctive member is not updated.  You must do so manually, using the IndexedList.Reindex method.  Given that an object can belong to any number of associated collections, it is too costly and problematic to do this automatically.

For more details about the effects of removing objects from collections see Deleting objects.

Ordered collections

You create an ordered collection by including the ordered qualifier in the member definition.  In the Library example application, stock copies is an ordered collection in the publication class, defined as follows

Each publication in the library is a stable persistent containing
   a nominative title,
   a distinctive ISBN number,
   several ordered stock copies
.

An ordered collection must be of several object, and the collection must have an element class in a category which has the allow order function, such as orderable.  See Class Category Definition  for details.  Persistate gives such classes a read only integer property called Order.  In ordered collections, Persistate ensures that each object in the collection is always at the position determined by the value of its Order property.

Caution

Because the ordering is based on a property of the contained elements, the ordering is valid in just one collection, even though it is possible for an object to be in any number of associated collections.  The way of achieving ordering may change in future versions of Persistate.

You use ordered members when you want each element in the collection to be always at the same index.  The following example adds a new book to the library along with four stock copies.

Book newBook = new Book("188829866", "Fly Fishing For Dummies");
for (int i = 0; i < 4; i++) {
   StockCopy copy = new StockCopy(LendStatus.Available);
   newBook.StockCopies.Add(copy);
}
The.Library.Publications.Add(newBook);

As each copy is added to the StockCopies collection, Persistate allocates a new order to each added object and sets its Order property accordingly.  These orders will be 0 to 3, and can be accessed as such, like this:

newBook.stockCopies[2].lendStatus = LendStatus.OnLoan;

Whenever Persistate retrieves a StockCopies collection from persistent storage, the elements are placed into the collection according to their Order values, so StockCopies[2] will always get the same object.  Furthermore, if you remove an object from within an ordered collection, remaining objects are not shuffled up – rather the position is left vacant, and set to null.  You will also get vacant positions when a non-contiguous ordered collection is retrieved from persistent storage.

You can set objects into an ordered collection using the single parameter indexer, the same as for all collections.  For example:

newPub.StockCopies[1] = new StockCopy(LendStatus.Unavailable);

This will remove any object which exists at that position, delete it if this is an actual collection, and replace it with the new one.  In an ordered collection, it also sets the value of the Order member in the new object to the position it is being set into – in this case 1.