Inheritance and Conversion

Posts   
 
    
garrett
User
Posts: 33
Joined: 21-Feb-2008
# Posted on: 26-Mar-2008 19:44:23   

Hi all,

Just wanted to get an idea for the best way to tackle a problem

I have two classes in a TargetPerEntity inheritance tree.

Visitor {}

and

User : Visitor {}

As soon as a user lands on the site they become a typeof(Visitor) so that they can store their searches etc to re-run later. The problem I have is how to down-convert if the visitor decides to register. i.e - i don't want to lose all the previous relations.

I could of-course do a massive move or clone of all properties and relations from the old Visitor object to the new User object then delete the old Visitor and save the new User but that seems a bit strenuous. Is there a shortcut?

Has anyone got any recommendations?

Many Thanks !!

Posts: 1263
Joined: 10-Mar-2006
# Posted on: 27-Mar-2008 20:23:02   

I have been through many discussions this particular issue with Otis.

The simple answer is to add the User entity into your entity list a 2nd time - this time not part of any inheritance. When they convert, you can simply add a record to that 2nd entity and it is now a 'user'.....

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 31-Mar-2008 21:25:15   

Exactly. Inheritace is about types. You also don't change a string typed object to an ArrayList and you find that natural, because string isn't an arraylist, it always will be a string. This is the same thing: just because data is mutable doesn't mean the types should be mutable.

So 'rolebased' inheritance isn't really a good choice for inheritance: if an entity instance can change type due to its data being updated, you shouldn't use inheritance.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 1263
Joined: 10-Mar-2006
# Posted on: 31-Mar-2008 21:32:34   

Otis, I will respectfully (still) disagree with you. And offer that a Grape, which is a subclass of fruit could change to a Raisin. Agree that a string should not become an ArrayList as they are not related....that does not mean that I cannot do the above...

But, I digress, we have been round and round on this - and once I had a solution for how to do it (the one I presented above), I just dropped it. However, this does happen even in 'good choices for inheritance'. I am using inheritance in multiple places and is a GREAT feature of your product - the only issue I have is in 'some circumstances' I need to change its type - so I just use a 2nd Entity.

smile

garrett
User
Posts: 33
Joined: 21-Feb-2008
# Posted on: 01-Apr-2008 02:27:43   

Hi Wayne. That sounds like an excellent (shortcut) solution. Thanks for the tip!

Otis, I know what you're saying and 99 times out of 100 would agree but this feels like a better fit when there are extra rules behind the scenes. I'd prefer to try and 'let the objects do the work' rather than writing validating and constraining code.

I'll re-examine my entities to see if there a 'cleaner' compromise.

gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 03-Apr-2008 10:22:46   

Hi All,

I've got a similar problem, I apart from the Grape -> Raisin example, I think the chances of the same happening in the documented examples is the same. It's not unthinkable to being a Employee first, then become a Manager and when you have retired think of becoming a BoardMember.

I've got a scenario like this described in thread: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=12894

In brief, we have a application with Clients and their Contactpersons (ContactEntity), now we need to extend the application to support Traningcourse Management, therefore some Contactpersons have to become Students. I made students a Sub-Type of Contact with an extra relation: Courses. (this is the diagram in DB and LLBL Designer: http://www.llblgen.com/TinyForum/Attachments.aspx?SourceType=1&MessageID=71683)

I thought I could use this, and when a Contact becomes a Student I would just create a StudentEntity for the Contact making it available as a Student. I someone would enter the system not being a Contact yet I would just create a Student and therefore automatically creating a Contact.

But after reading this thread I am not that sure anymore. I must say this is the first time I am thinking of utilizing Inheritance but I am still not 100% clear on this.

Any discussion and comments would be greatly appreciated to get a less blurred view. I give my own example just to explain where I am coming from, but abstract or other examples are evenly welcome, I'm not looking for the perfect solution for my problem but for full understanding of how and when to use inheritance!

Thanks! Gab

garrett
User
Posts: 33
Joined: 21-Feb-2008
# Posted on: 03-Apr-2008 12:27:38   

I guess a good outline of the benefits and pitfalls of going with the inheritance option (as opposed to others) would be useful.

Pros: - Makes the structure more logical (in my mind at least). A student is a kind of contact as is a teacher - Means I don't have to write and support code to constrain flat entities and which relations can be manipulated depending on that entities current role. - Imagine the number of fields on a table were you to represent all possible types as one flat entity.

Cons: - Doesn't fit a code purist model because you have extra data (changing | upgrading | refining) an entities type - Conversion isn't the easiest (bar using Wayne's shortcut) as you'd have to update every foreign key referencing the object from base class up to the 'new' entities id. - Large hierarchies will suffer performance wise (though this is true of all inheritance not just role based)

I'm sure there are other but they'd don't come to mind as quickly as those above. Maybe Otis and or Wayne could dispel some of these or add to them from their experience and knowledge

Posts: 1263
Joined: 10-Mar-2006
# Posted on: 03-Apr-2008 15:34:51   

The inheritance feature is great and I love it. The only "real problem" I have with it is in the case i have to change types like you mention above.

However, it is a very simple solution/workaround also.

1) If you create a 'teacher', when the student does not exist - everything will work great. 2) If you want to convert a student to a teacher, you will have to add a non-inherited teacher entity to your llblgen project (just add the teacher entity a 2nd time, make sure it has no inheritance info). Once you have done that, to convert a student to a teacher, you simply create a new TeacherNoInheritance entity and assign it the key from the Student and save. Done....

Number 2 can easily be done from a new method on your regular 'Student' class:


    //self servicing example
    public Teacher ConvertStudentToTeacher()
    {
          NonInheritTeacher nht = new NonInheritTeacher();
          nht.StudentId=this.StudentId;
          nht.Save();
          return nht;
    }

Otis! You need to get coderush working in this editor so I dont actually have to code a function myself! sunglasses

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 03-Apr-2008 16:52:31   

Coderush? What's that? Oh! That add-in which adds all kinds of animated arrows etc to the editor,right? wink

For the record: I understand that it's easy to change a couple of values in a table and that that would make life in THIS case easier for some, but make no mistake: in database land: once you move away from the edge of correctness, you can't be sure if your data is what it says it is. With inheritance being implemented as 1 entity over multiple tables, it makes things complicated when you're at the table level. With the knowledge that databases outlive applications, it's key the data is correct, at all times. So, if you want to have changing types, either migrate the data to differnt types or use a role system (so Employee has JobId, instead of having Manager, BoardMember etc. )

Frans Bouma | Lead developer LLBLGen Pro