How to implement a 1:1 relationship?

How to implement a 1:1 relationship?

Old forum URL: forums.lhotka.net/forums/t/9797.aspx


superkuton posted on Tuesday, November 23, 2010

The database i have been working on has several 1:1 relationship that i need to implement in BOs.

As an example, I have the following tables:

CONTACT.PERSON

ID

LastName

FirstName

MiddleName

 

PERSON.DETAIL

ContactID

Sex

MaritalStatus

BirthDate

BirthPlace

 

CONTACT.ADDRESS

ContactID

Street

Barangay

Municipality

 

A sample BO that I need to create would be the Candidate ERO with the following properties:

ID

LastName

FirstName

MiddleName

Sex

MaritalStatus

BirthDate

BirthPlace

Street

Barangay

Municipality

 

There are records in the Contact.Person table that has no equivalent records in the Person.Detail and Contact.Address. But in the Candidate BO, the user can add the Person.Detail and Contact.Address records.

I can no longer change the database tables structure. How do I implement my business object?

Thank you in advance.

tiago replied on Tuesday, November 23, 2010

Hi superkuton

I would say that PERSON.DETAIL and CONTACT.ADDRESS are childs of CONTACT.PERSON

As to Candidate BO, I don't care if he lives in the same database table and has the same childs of CONTACT.PERSON. If it's a different use case, it's also a different BO. The point is:

ajj3085 replied on Tuesday, November 23, 2010

I would recommend simply have all the fields on one BO, unless you can resue exactly the address and / or detail.  If you can reuse either one (the behavior is the same in another use case), then go with the child BOs.  But if not, I wouldn't make the BO more than one class, and it can hide the details of where exactly the data is stored.  Don't model your BOs according to your tables, model them how to best fit your use case.  This will make your application more maintainable, and your UI easier to code.

I wouldn't go the child BO route unless I could reuse them, because this will make your binding to the UI more complex than it needs to be.

To answer your question if you don't want a flat model, just create Address and Detail as normal child objects.  When you create / fetch the root BO, you can simplly call an interal factory method to create / fetch the children, as I would assume they should never be null.  (Again, the properties on the root to the child could always have a value and the child BO can determine whether or not a row is even needed in the table).

 

JonnyBee replied on Tuesday, November 23, 2010

I'll join in with Andy and recommend a flattened business object.

You can use SQL with outer joins to fetch data -  and only save/update date when there is data to update in your Save method.

I'd also like to point out that BusinessRules often get  simpler when you have a flattened structure.
F.ex -address may have different required rules dependent on whether the parent is a person or a company.

superkuton replied on Wednesday, November 24, 2010

Thanks to all of you for your replies guys.

Just like JonnyBee has repeatedly been suggesting to me, I should go the "flattened" structure (creating a single Candidate ERO) way. However, there are things that I am bothered yet.

This is my problem:  in the existing database, there are Contact.Person records that does not have any matching Contact.Address and Contact.Detail records. When a Candidate ERO is created and presented to the UI, the user may add the Candidate address and detail entries. How would  I now save the new address and detail records?

FETCH  - I can fetch the matching address and detail records using SQL joins and subqueries.

UPDATE - If there are existing address and detail records, i can update them using normal SQL procedures.

INSERT  - Herein lies my problems:

How can the ERO insert a new instance of address and detail records for an already existing Contact.Person record?

If the ERO object fecthes a Candidate ERO which has not yet any Contact.Address and Person.Detail records, how does it create them into the database?

What procedures do I need to implement in the Candidate ERO to save the new records into the child tables?  Or what SQL procedures do I need to implement?

Please help me guys. Thank you.

 

ajj3085 replied on Wednesday, November 24, 2010

Well, your flattened BO would have a property which holds the AddressId.  Make that a nullable int, and your BO can use that to determine if there's an address or not when saving.  Remember, your BO should have all the data it needs to fulfill its use case.  If a matching record doesn't always exist, then the BO needs to keep that bit of information with it.  You'll likely need the AddressId anyway to update the Contact.Address record which is already there; you can use that to also determine if there's a record there at all.

superkuton replied on Wednesday, November 24, 2010

Thank you very much Andy.

Yes, this use case requires that an address and  a detail record should exist for the BO.

(There are also use cases in the application that allows inserting a record into the Contact.Person table without any corresponding address or detail records.)

I wouldn't have any problem in creating a new Candidate object because all properties required by the BO will be inserted into the corresponding tables.

If in my Candidate ERO use case, however,  when a Candidate is loaded and found not to have yet address and detail records, how will I insert new records? In such a case, I will be updating the Candidate, but in the database I will be doing the following:

UPDATE the Contact.Person record if there are changes

INSERT a new record in the Contact.Address table, and

INSERT a new record in the Person.Detail table.

 

Should this implementation be done in the BO or in the Stored Procedures? How will we do it?

Thank you, once again.

 

ajj3085 replied on Wednesday, November 24, 2010

Well, how you get the data into the database is irrelevent; do whatever you need to for your environment.  The BO can determine, based on the information it has, if it needs to insert the records or not.  Just because you're code is in a DataPortal_Update doesn't mean you can insert, update, or delete rows.  DP_U just means the BO exists in your system already and you're modifying it.  But you can make it smart enough to do whatever data operations you want.

Copyright (c) Marimer LLC