TargetPerEntityHierarchy - Changing Type

Posts   
 
    
simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 25-Aug-2020 19:20:22   

(Still on LLBLGen Pro v4.2 and going strong!)

I have an Entity called Resource which has 14 discriminator values which represent types of Resources found in a Library.

Some Resources I'm importing get assigned the 'wrong' type because the other system data is crap, so I need to be able to correct them in my Grids. (I seem to recall I used TargetPerEntityHierarchy specifically for this eventuality since it one table and the 'optional' fields are nullable)

I have attached a screenshot showing a small part of the Instance Information - mainly the bit where I allow Book to also be split into TextBook and EBook because they are the only 3 values that use additional fields.

I may have asked this a long time ago and you may have told me that it isn't possible/not supported/not desirable to change Discriminator values. But I can't find such a thread and I am literally losing my mind so forgive me if I'm asking again:

My plan is add a custom method to ResourceEntity to alter the Type string (since there is no setter for the Type property) and, if moving **from **B, TB, EB then set the four fields shown in the image to null too.

Can you foresee any problems doing this?

Attachments
Filename File size Added on Approval
1.png 90,173 25-Aug-2020 19:20.32 Approved
daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 26-Aug-2020 07:36:20   

simmotech wrote:

I may have asked this a long time ago and you may have told me that it isn't possible/not supported/not desirable to change Discriminator values. But I can't find such a thread ..

I didn't find that old thread neither.

simmotech wrote:

My plan is add a custom method to ResourceEntity to alter the Type string (since there is no setter for the Type property) and, if moving **from **B, TB, EB then set the four fields shown in the image to null too.

Can you foresee any problems doing this?

I don't think is is the way to go. Changing the type string won't change the type of the object which could lead to other problems. I would suggest to remove that entity, create another with the correct type and add it to the collection to be saved.

David Elizondo | LLBLGen Support Team
simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 26-Aug-2020 09:53:02   

I don't think is is the way to go. Changing the type string won't change the type of the object which could lead to other problems. I would suggest to remove that entity, create another with the correct type and add it to the collection to be saved.

But changing the type string does change the type of object (for TargetPerEntityHierarchy not TargetPerEntity). Not any already in-memory entity of course but the next fetch would create an entity of the new type.

Creating another entity is not an option BTW - there are too many related entities which would have to be unpicked before it could be recreated as new entity.

I suppose my question was more about how the additional fields (the 4 additional ones shown on the attached image - only relevant for Book & inheritors) are treated if they have non-null values but the object is no longer a Book - are they just ignored?

My guess is that those values stay in the database and are effectively ignored if the entity type is non-Book. But if it got change back to Book again then their values would be seen again.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 27-Aug-2020 07:48:31   

simmotech wrote:

But changing the type string does change the type of object (for TargetPerEntityHierarchy not TargetPerEntity). Not any already in-memory entity of course but the next fetch would create an entity of the new type.

That was my observation: the in-memory object type.

simmotech wrote:

I suppose my question was more about how the additional fields (the 4 additional ones shown on the attached image - only relevant for Book & inheritors) are treated if they have non-null values but the object is no longer a Book - are they just ignored?

My guess is that those values stay in the database and are effectively ignored if the entity type is non-Book. But if it got change back to Book again then their values would be seen again.

I didn't try it before, but my guess is that too. However I think this is not guaranteed that works neither between version updates.

Changing the entity type at runtime (in-memory) isn't supported: if you need it, you shouldn't use inheritance. Also, inheritance in entity models is a result of 'interpreting' the data in the db. So manipulating it at runtime could lead to invalid data with respect to inheritance.

So, if you test this and need to use it, then lets go, however I think IMHO that the original problem (invalid data in DB) should be fixed in that arena (using transformation services, migration tools, sanity data checks, triggers, SPs, etc), not in the model and data access layer.

David Elizondo | LLBLGen Support Team
simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 28-Aug-2020 08:38:43   

Sorry - mustn't have been clear enough in the original message.

This is a maintenance issue where the user sees in a list items that are of an incorrect type. They select one or more incorrectly typed items and can choose the correct type from a context menu. My app will then change the type string and the list will refresh itself.

The data I have is imported from a rival system (where it was incorrectly set in the first place). It isn't possible to detect incorrect types during the import so I need to have a way of changing it in my app and I sort of prepared for this by using the inheritance system that used a single table to keep it simple.

My question is sort of about what you referred to as 'invalid data': The Book type (and its two inheritors) have 4 additional fields as shown on that original attached image. They are all nullable fields so going from a non-Book to a Book is fine. If the original was a Book and had some of those fields set to non-nullable values but then the type was changed to a non-null type, are they just left in the database but ignored? Or does LLBLGen 'interpret' this as invalid data and throw?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 28-Aug-2020 10:27:21   

If you change the discriminator value of an entity instance (so the table row contents), its 'type' changes so the next load of that entity instance will result in an instance of a different entity class in memory. This could lead to problems when you still have an instance of the entity in an instance of its old entity class in memory and try to persist that.

However as you describe it, it's a one time thing and the entity instances in question are changing types by that system just once, and are then used in their new type from then on.

I think the confusion earlier in the thread was caused by the assumption you'd like to change types at any time frequently, which isn't something one should do (in that case, use a related entity with 'type' specific data and no inheritance. Like a 'role' entity on a 'user' entity instead of deriving entities from 'user' describing the role a user has).

So TL;DR: if it's a one time correction thing: sure go ahead, just make sure changing the type of an entity instance doesn't conflict with having that entity in memory somewhere as well.

Frans Bouma | Lead developer LLBLGen Pro
simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 01-Sep-2020 09:02:49   

Thanks for the confirmation. Yes, it is a one-time change thing.