Problem with a TargetPerEntityHierarchy sub-type in a typed list

Posts   
 
    
Roman
User
Posts: 23
Joined: 19-May-2006
# Posted on: 14-Jun-2006 23:43:26   

Hi,

I am running into the following problem. I have a generic Type table that looks like this:

Type

1 A Desc1 2 A Desc2 3 B Desc3 4 B Desc4

The first field is the PK, and the second is the discriminant column used to create two specific Type entities - TypeA and TypeB (TargetPerEntityHierarchy). The third field is description. Now imagine I have a SomeData table with one field being a FK onto TypeA. I have created the relation in the designer as well.

I now create a new typed list based off of SomeData and I want to include the description of the TypeA field. No problem - I generate, compile, and run. The typed list is bound to a GridView and all data seems to be there. So far so good.

Now I try to mess up the data in the DB and manually insert Type record 3 into SomeData's TypeA foreign key. This is semantically illegal, since 3 is a TypeB object. The DB doesn't complain of course, since the FK reference itself is legal, but I figured LLBLGen would take of the type semantics. No cigar - the grid happily displays Desc3 as the description.

Is that by design or am I missing a step somewhere?

Thanks!

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 15-Jun-2006 07:35:25   

Better to try setting the related entity by assigning an entity object to the related entity field, rather than using the FK directly (Type checking is possible, but I don't think value checking is possible)

CustomerEntity myCustomer = new CustomerEntity("CHOPS");
OrderEntity myOrder = new OrderEntity();
myOrder.Customer = myCustomer; 

Rather than:

OrderEntity myOrder = new OrderEntity();
myOrder.CustomerID = "CHOPS"; 
Roman
User
Posts: 23
Joined: 19-May-2006
# Posted on: 15-Jun-2006 18:00:21   

Walaa - I am not sure if I understand your answer. My original question has to do with a typed list returning a TypeB value in a TypeA field. In my mind, an empty value should be returned in the list, since the value in the database is semantically invalid.

I did not write any code other than to fetch the list and bind it to the grid.

Roman
User
Posts: 23
Joined: 19-May-2006
# Posted on: 15-Jun-2006 20:27:01   

Just ran into a related problem with a dynamic list. Here's a sample of the code (going with the original TypeA, TypeB example):

ResultsetFields fields = new ResultsetFields(2); fields.DefineField(TypeAFieldIndex.ID, 0, "ID"); fields.DefineField(TypeAFieldIndex.Description, 1, "Description");

DataTable dt = new DataTable(); DataAdapter.FetchTypedList(fields, dt, null, 0, null, true);

The datatable contains ALL of the records from the Type table instead of just TypeA records. Why???

Thanks again for your help!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 15-Jun-2006 21:01:49   

What you want is only possible if the descriminator column is in the FK/PK combination. If you've checked, the relation to the entity Type is using the supertype entity /root entity, not type A nor type B. This means that SomeTable has a relation with the roottype, and therefore any type A or type B can be related to a SomeTable instance.

Frans Bouma | Lead developer LLBLGen Pro
Roman
User
Posts: 23
Joined: 19-May-2006
# Posted on: 15-Jun-2006 22:42:51   

There are currently two relations on the SomeData entity - one to the Type entity (created implicitly due to a FK reference) and another to the TypeA entity (created manually). Moreover, the typed list only has TypeA selected in its list of entities, and not Type. The relation between SomeData and TypeA is explicitly used in the designer's typed list editor. It seems this should be enough for the typed list to make inferences about the underlying data type.

I don't understand what you mean by "FK/PK combination" - could you give some additional details, please?

Finally, the problem I described in my last message is very simple - read all data from the TypeA table using a dynamic list, no relations or FKs involved. Why does that return all Type data?

Thanks.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 16-Jun-2006 17:16:41   

Roman wrote:

There are currently two relations on the SomeData entity - one to the Type entity (created implicitly due to a FK reference) and another to the TypeA entity (created manually). Moreover, the typed list only has TypeA selected in its list of entities, and not Type. The relation between SomeData and TypeA is explicitly used in the designer's typed list editor. It seems this should be enough for the typed list to make inferences about the underlying data type.

I don't understand what you mean by "FK/PK combination" - could you give some additional details, please?

That the PK consists of 2 fields, namely also the discriminator column.

Finally, the problem I described in my last message is very simple - read all data from the TypeA table using a dynamic list, no relations or FKs involved. Why does that return all Type data? Thanks.

You can filter on which types to fetch by adding a typefilter to the predicate expression. See Using the generated code -> Selfservicing/Adapter -> Filtering and sorting -> Advanced filter usage -> Filtering on entity type.

Frans Bouma | Lead developer LLBLGen Pro
Roman
User
Posts: 23
Joined: 19-May-2006
# Posted on: 16-Jun-2006 18:38:54   

OK, I can live with filtering on entity type, though I am surprised filtering needs to be involved at all - I think there should be a direct way of retrieving data from sub-types. Right now they are treated as second-class citizens (compared to regular entities) it seems.

If I understand you correctly, adding the discriminator to the PK allows LLBLGen to treat the sub-types as completely unrelated entities. So this would be possible:

Type

1 A Desc1 2 A Desc2 1 B Desc3 2 B Desc4

I don't really want that, since now SomeData table has to have two fields for a foreign key reference into Type. Still not seeing why the generated cannot distinguish between the different sub-types based on the discriminator field alone.

At this point I only see two options for myself - get rid of the Type table and create a whole bunch of smaller TypeA, TypeB tables with separate entities each. Or just have one Type entity and just filter on the discriminator field manually. Bah - using sub-types would've been much cleaner, IMO...

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 16-Jun-2006 19:04:49   

Roman wrote:

OK, I can live with filtering on entity type, though I am surprised filtering needs to be involved at all - I think there should be a direct way of retrieving data from sub-types. Right now they are treated as second-class citizens (compared to regular entities) it seems.

No they're not, you just have a relation between A and B where B has subtypes but that's unimportant: A has a relation with B, so all subtypes of B will be valid for that relation, thats the point here.

Frans Bouma | Lead developer LLBLGen Pro
Roman
User
Posts: 23
Joined: 19-May-2006
# Posted on: 16-Jun-2006 21:19:52   

Otis wrote:

Roman wrote:

OK, I can live with filtering on entity type, though I am surprised filtering needs to be involved at all - I think there should be a direct way of retrieving data from sub-types. Right now they are treated as second-class citizens (compared to regular entities) it seems.

No they're not, you just have a relation between A and B where B has subtypes but that's unimportant: A has a relation with B, so all subtypes of B will be valid for that relation, thats the point here.

But in my case A also has a defined relation with a subtype of B. THAT relation does not seem to be used, which is what I have a problem with. The generated code reverts to the A<->B relation instead of using the proper (IMO) A<->Bsub.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 17-Jun-2006 10:48:51   

They you have to be more specific because you said:

The first field is the PK, and the second is the discriminant column used to create two specific Type entities - TypeA and TypeB (TargetPerEntityHierarchy). The third field is description. Now imagine I have a SomeData table with one field being a FK onto TypeA. I have created the relation in the designer as well.

You defined a FK constraint, which can only be using the table which contains all the types. Hence my conclusion the actual relation is between the root type of the hierarchy and SomeData. simple_smile

What's unclear to me is what's the exact hierarchy of the types in Type ?

Because if you have this: RootType <- A RootType <- B

and NO FK between SomeData and Type, you can then define a relation between SomeData and A. This gives a field mapped onto the relation in SomeData, lets call that field A. This gives thus a property in SomeData's entity of type A. You then can't set that property to an instance of B as that's not compilable code

However, as it's described in the concepts section of the documentation: if you want a specific relation between a subtype and another type, use a hierarchy type of TargetPerEntity, simply because it's undoable for the code to check if an FK is really valid, because it would come down to the fact that it has to perform FK-style checking on a related table when an update occurs, while you get that for free when you use a different hierarchy type: TargetPerEntity.

Frans Bouma | Lead developer LLBLGen Pro
Roman
User
Posts: 23
Joined: 19-May-2006
# Posted on: 19-Jun-2006 18:23:41   

Thank you, Otis; I have come to the same conclusion as well - TargetPerEntity makes more sense in this scenario.

Thanks for being so patient :-)

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 19-Jun-2006 18:38:31   

No problem simple_smile .

Frans Bouma | Lead developer LLBLGen Pro