Associations in DC

XAF Team Blog
29 September 2008

EDIT:
Domain Components (DC) is in maintenance mode and we do not recommend its use in new software projects.

This post is one in a series about our work on Domain Components (DC) framework and related component libraries. I’m just describing what we are working on, what problems we are facing and what results we've got so far.

In my previous post I was looking at INote interface:

	public interface INote {
		string Text { get; set; }
		IItemWithNotes Owner { get; set; }
	}

There is another thing I don’t like in this code: I don’t want the INote interface to know about the IItemWithNotes interface. But currently in XPO I have to define back references. Why? Let me explain the problem. Look at the class structure below:

    public class Developer : XPObject {
        private string name;
        public Developer(Session session) : base(session) { }
        public string Name {
            get { return name; }
            set { SetPropertyValue("Name", ref name, value); }
        }
        [Association]
        public XPCollection Notes { get { return GetCollection("Notes"); } }
    }
    public class Note : XPObject {
        private string text;
        public Note(Session session) : base(session) { }
        public string Text {
            get { return text; }
            set { SetPropertyValue("Text", ref text, value); }
        }
    }

These classes won't work correctly in XPO. In a relational database, a One-to-Many relation is performed by adding a foreign key to the table. For the classes above, you would create a table structure where the Note table has the foreign key column that stores a Developer's OID:

DC2-01

To retrieve the Notes that are associated with a particular Developer ID, you would write an SQL query like this: "select * from Note where Developer = <developer id>". XPO generates all queries for you. To generate the query I showed to you, XPO requires that the Note class has a property mapped to a foreign key column. In other words, the Note class should look like this:

    public class Note : XPObject {
        private string text;
        private Developer developer;

        public Note(Session session) : base(session) { }
        public string Text {
            get { return text; }
            set { SetPropertyValue("Text", ref text, value); }
        }
        [Association]
        public Developer Developer {
            get { return developer; }
            set { SetPropertyValue("Developer", ref developer, value); }
        }
    }

In this instance, XPO will find both ends of the Developer-Note association and create all necessary constraints and foreign keys.

But I’m working on the Domain Component library. My goal is to provide a framework for domain components – a puzzle's independent pieces. While writing the Note component, I don’t want it to know how anybody uses it. For instance, it can be used in the following entity (I know this is not a good design, but I still think it should be possible to do so):

    public interface IFullOfNotes {
        IList<INote> PublicNotes { get; }
        IList<INote> PrivateNotes { get; }
        IList<INote> DraftNotes { get; }
    }

To map the IFullOfNotes to the database, the Note table should have three foreign keys. If the XpoBuilder can generate back-reference (foreign key) properties automatically, our DC components will be much more flexible.

So, I want to write the following code in my Notes library:

	public interface IItemWithNotes {
		IList<INote> Notes { get; }
	}

	public interface INote {
		string Text { get; set; }
	}

I've added tests that express my desire. And again… I'm waiting for an answer from the XPO team. Stay tuned.

Free DevExpress Products - Get Your Copy Today

The following free DevExpress product offers remain available. Should you have any questions about the free offers below, please submit a ticket via the DevExpress Support Center at your convenience. We'll be happy to follow-up.
Tags
No Comments

Please login or register to post comments.