Daniel Flower Dot Com Banner

Object Inheritance Example

The example on this page illustrates how multi-level inheritance is used in Shunde.  This is significant becase normally it is very difficult to store objects  which have multi-level inheritance (e.g. Object type C extends type B which extends type A) in a relational database (see this page for a full discussion on this problem).

We will continue the example from the previous page with a Car object.  We want the owner of the car to be a Person or an Organisation.  From a legal standpoint, people and organisations are considered to be quite similar (they can own things, pay taxes, have a lifetime, etc), and so we could consider that they both extend the same type.  In this example, we will call this common type a Party.  We would then want to say that the owner of a Car is a Party, which can of course be either a Person or an Organisation.

The following code shows the Party, Person, and Organisation class models in C#:

 
using System;
using Shunde.Framework;


namespace TestSpace
{

    /// <summary>
    /// A Party object, which can be a person or an organisation
    /// </summary>
    public abstract class Party : DBObject
    {


        private string phoneNumber;

        /// <summary>Gets the full name of this Party, i.e. the organisation name or the persons first and last names</summary>
        public abstract string FullName
        {
            get;
        }

        // ... get and set for phone number ...

        /// <summary>Sets up the ObjectInfo for this class</summary>
        static Party()
        {

            DBTable tbl = new DBTable("Party", new DBColumn[] {
                new DBColumn( "phoneNumber", typeof(string), 0, 20 )
            });

            ObjectInfo.RegisterObjectInfo(typeof(Party), tbl);

        }

    }

    /// <summary>
    /// A Organisation
    /// </summary>
    public class Organisation : Party
    {


        private string name;

        // ... get and set for name ...

        /// <summary>Gets the name of the organisation</summary>
        public override string FullName {
            get { return this.name; }
        }

        /// <summary>Sets up the ObjectInfo for this class</summary>
        static Organisation()
        {

            DBTable tbl = new DBTable("Organisation", new DBColumn[] {
                new DBColumn( "name", typeof(string), 1, 100 )
            });

            ObjectInfo.RegisterObjectInfo(typeof(Organisation), tbl);

        }

    }


    /// <summary>
    /// A Person object
    /// </summary>
    public class Person : Party
    {

        private string firstName;

        private string surname;

        // ... get and set for names ...

        /// <summary>Gets the first name and surname of this Person</summary>
        public override string FullName
        {
            get { return this.firstName + " " + this.surname; }
        }

        /// <summary>Sets up the ObjectInfo for this class</summary>
        static Person()
        {

            DBTable tbl = new DBTable("Person", new DBColumn[] {
                new DBColumn( "firstName", typeof(string), 1, 50 ),
                new DBColumn( "surname", typeof(string), 1, 50 )
            });

            ObjectInfo.RegisterObjectInfo(typeof(Person), tbl);

        }

    }

}
 
Now in the Car class, we can say the the owner is a "Party":
 
using System;
using Shunde.Framework;

namespace TestSpace
{

    /// <summary>A Car object, which extends the Shunde DBObject class</summary>
    public class Car : DBObject
    {

        private string make;

        private int year;

        private Party owner;

        // ... Get and Set methods go here ...

        /// <summary>Declares the fields, and their accepted values, for this class</summary>
        static Car()
        {

            // Declare a database table, named "Car", with the following columns:
            DBTable tbl = new DBTable("Car", new DBColumn[] {

                // The "make" is a string, with minimum length 1, maximum length 50
                new DBColumn( "make", typeof(string), 1, 50 ),

                // The "year" is an integer, null not allowed, minimum value 1900, no maximum value
                new DBColumn( "year", typeof(int), false, 1900, null ),

                // The owner of the Car, which is a DBObject type
                new DBColumn( "owner", typeof(Party), false )
            });

            // Tell the Shunde Framework about this class
            ObjectInfo.RegisterObjectInfo(typeof(Car), tbl);

        }


        /// <summary>Gets all the Car objects in the database filtered by the given <see cref="Person">owner</see></summary>
        public static Car[] GetCarsBelongingTo(Party owner)
        {

            // To get all objects in the database is very easy:

            // First get reference to the type of DBObject in question:
            Type t = typeof(Car);

            // Then get the info Shunde holds about this DBObject type:
            ObjectInfo oi = ObjectInfo.GetObjectInfo(t);

            // Get the "SELECT ... FROM ... " SQL from the Object Info, and append a where clause:
            string sql = oi.GetSelectStatement() + " WHERE [Car].[ownerId] = " + owner.Id;

            // Execute the query:
            return (Car[])DBObject.GetObjects(sql, t);

        }


    }

}
 

We can now get a car object, populate its owner, and print out its name.  The owner could be an organisation or a person, but because we are simply calling the abstract Get property FullName defined on the Party object, we don't even need to know which it is.  Organisations and people can be set as the car's owner as well: 

 
using System;
using TestSpace;

/// <summary>An ASP.NET webpage</summary>
public class Default_aspx : TextSpacePage
{

    public override void Start()
    {

        // Get a car object from the database
        Car car = new Car();
        car.Id = GetIntParam("carId");
        car.Populate();

        // Populate the owner object - this could be a Person or an Organisation, but we don't need to know in this code
        car.Owner.Populate();
        Response.Write("The car is owned by: " + car.Owner.FullName);

        // We can change the owner to a person:
        Person frank = new Person();
        frank.FirstName = "Frank";
        frank.Surname = "Rogers";
        frank.PhoneNumber = "09-555-444";
        frank.Save();

        car.Owner = frank;
        car.Save();

        // Or an organisation:
        Organisation moneyCorp = new Organisation();
        moneyCorp.Name = "Money Corp";
        moneyCorp.PhoneNumber = "09-444-555";
        moneyCorp.Save();

        car.Owner = moneyCorp;
        car.Save();

    }

}
 
Comments for this page
gFBsuumZWCTCcF
posted by Klaudia on 1/10/2012 4:30:15 a.m. (NZ time)
Yo, that's what's up trtuhuflly.
Add your comment below
Your Name:
Comment Title:
Comment: