Create the Class Travel

using System;

using System.Collections;

using NDO;

namespace BusinessClasses

{

    [NDOPersistent]

    public class Travel

    {

        string purpose;

        public string Purpose

        {

            get { return purpose; }

            set { purpose = value; }

        }

        public Travel()

        {

        }

    }

}

This class follows the same pattern as the class Employee. Again the property Purpose can be created with the Add Accessor tool.

The Relation between Employee and Travel

Now the class Employee needs a reference to the class Travel and a property for public access.

You also have to make sure that the namespace System.Collections (System.Collections.Generic if you use the .NET generics) is included since you will work with ArrayLists and the interface IList. The namespace statement is created automatically by the Add Persistent Class feature of NDO. The relation to the travel objects is implemented as follows:

[NDORelation(RelationInfo.Composite)]

List<Travel> travels = new List<Travel>();

Meanwhile you know the attribute NDORelation. The declaration RelationInfo.Composite is also known from the relation between Employee and Address.

Important: Be sure to initialize the list variable with a new list, either in the constructor or in the declaration as shown above. If the initialization is done in the declaration, it takes effect in all constructors. Not initializing the list may result in a null pointer exception.

For this sample we need a slightly different accessor property than what we got to know so far. It is not sufficient to simply pass on the list to the outside using a property. This would allow adding or removing elements outside the class Employee. But the NDO framework would not be able to detect such changes. The following code is generated if you click on the declaration of the variable travels and select Add Accessor in the NDO toolbar:

public IEnumerable<Travel> Travels
{
    get { return this.travels; }
    set { this.travels = value.ToList(); }
}
public Travel NewTravel()
{
    Travel t = new Travel();
    this.travels.Add(t);
    return t;
}
public void RemoveTravel(Travel t)
{
    if (this.travels.Contains(t))
        this.travels.Remove(t);
}

The factory method NewTravel() is generated, because the relation is a composite relation. Composite means that the life cycle of child objects (Travels in this case) is coupled to the life cycle of the parent object (Employee in this case). So it makes sense to create them inside the class Employee to force the attachment to the right parent object. In such situations the Factory Method pattern is applied. It ensures that the Travel object is always assigned to the right parent. Once a travel object is created, it is also visible outside the class Employee, as it is supposed to be. The function RemoveTravel() allows removal of travel objects from the list. As we have a composite relation here, NDO deletes the objects from the database after removal from the list and calling Save().

The get property exposes an Enumerable of the Travel list to the outside. This allows displaying the Travel objects in a user interface. There is no way to delete or to add a Travel object from the ReadOnly list.

The set property allows assigning a ready prepared list of travel objects. The objects in the list must not be persistent. This would be contrary to the logic of the composite relation. The situation would be inverted if the relation is not of type composite. Here an exception would be thrown if the objects were not persistent. This behavior ensures the integrity of the database and is further explained in the chapter Relations in NDO.

The Expression

set { this.travels = value.ToList(); }

needs the System.Linq namespace.

Do not forget to update the database with the SQL script after rebuilding the assemblies.