Vertical Inheritance Issue

8 posts, 1 answers
  1. Mark
    Mark avatar
    5 posts
    Member since:
    May 2013

    Posted 26 Jun 2014 Link to this post

    We're trying to inherit from a one-to-one relationship between tables in SQL Server by following on the instructions on this page:

    http://docs.telerik.com/data-access/developers-guide/data-access-domain-model/working-with-associations/developer-guide-domain-model-working-associations-one-to-one

    We're able to delete the association, inherit from the "child" to the "parent" (and get the nice arrow), and set the inheritance on the "child" to "Vertical" and "Full Class Name", but that's where things start going wrong.

    When we go to the parent, and attempt to type "{no}" into the custom textbox, it won't stay there. When we close the mapping window, it disappears.

    Then, when we attempt to delete the "Id" column out of the child (primary key), we get the follow errors when we compile:

    Error 2 The meta constraint 'FK_XXXXXXXX_XXX' contains a source column 'Id' which is not part of the source table 'XXXXXXX'.
    Warning 1 The 'XXXXXXX' table does not have primary key columns specified.

    Any ideas?
  2. Answer
    Boyan
    Admin
    Boyan avatar
    100 posts

    Posted 01 Jul 2014 Link to this post

    Hello Mark,

    From the information you have provided, it seems that one possible reason for this behavior is the table that contains the foreign key does not participate as child in the inheritance hierarchy but as a parent.
    As the model is created, you will notice numbers above each association end. The one that is 0..1 should be the parent. Could you please confirm that this is indeed the case?

    I am looking forward for your feedback. 

    Regards,
    Boyan
    Telerik
     
    OpenAccess ORM is now Telerik Data Access. For more information on the new names, please, check out the Telerik Product Map.
     
  3. DevCraft banner
  4. Mark
    Mark avatar
    5 posts
    Member since:
    May 2013

    Posted 01 Jul 2014 in reply to Boyan Link to this post

    Hi Boyan,

    Isn't that backwards?

    If my tables (classes) are Animal and Dog, then I'll have an identity primary key in Animal, and Dog will have an Id column (primary key) that matches, so I'll have a 1-to-1 relationship. Animal has to be the parent, so the Animal side of the association will have a "1", and Dog will have "0..1" - since every Dog is an Animal, but not every Animal is a Dog. Dog must inherit from Animal, so the inheritance arrow should go from Dog and point to Animal.

    I have screenshots, but I don't see anyway to post them on this forum.

    Am I missing something?
  5. Boyan
    Admin
    Boyan avatar
    100 posts

    Posted 03 Jul 2014 Link to this post

    Hello Mark,

    I see your point.
    The documentation article in question actually describes the approached used in versions of Telerik Data Access prior Q2 2012 when out of the box support for one-to-one association was introduced. This means that the domain model will now automatically represent each one-to-one association defined in the database as described here
    We would like to thank you for your feedback and we would make sure to revise the article accordingly.

    That being said, I would like to ask you if you could describe your implementation scenario that requires one-to-one association to be re-mapped using vertical inheritance so we could advice you better. Could the same be achieved with the default one-to-one association mapping? If so, I would suggest you to use this approach.

    I am looking forward to hearing from you.
     
    Regards,
    Boyan
    Telerik
     
    OpenAccess ORM is now Telerik Data Access. For more information on the new names, please, check out the Telerik Product Map.
     
  6. Mark
    Mark avatar
    5 posts
    Member since:
    May 2013

    Posted 03 Jul 2014 Link to this post

    Hi Boyan,

    Thanks for the clarification. The situation described in the document you referenced is a different case. There, they are segmenting a single logical row into 2 or more tables to keep the row lengths smaller and preserving the most useful information in the "parent", while offloading some of the lesser used info to the "child" table(s) (although I think there's a typo in the article since, in the example at the bottom, they are setting the CustomerId to 1 in the "parent" and the CustomerDetailId to 2 in the "child" - shouldn't they be the same?). In any case, the article rightly states that this setup is not appropriate for Vertical Inheritance. I agree.

    Our situation is different. We have a User table, a Member table, and a USResident table.

    User <-- Member <-- USResident

    The User table contains common information (Name, Email, etc). A Member is a User, but we need to capture additional information for them (like a membership start date, etc). A USResident is a Member, but we need even more info for them (like a Tax Id Number).

    The User table has an identity (int) primary key. The Member table has an int (non-identity) primary key which matches 1 row in User (although there will be rows in User which are not Members, so the association will be User(1) - Member(0..1). A USResident will also have an int (non-identity) primary key which matches 1 row in both Member and User (although there will be rows in Member which are not USResidents, so the association will be Member(1) - USResident(0..1). Ultimately, the Id (primary key) columns should be removed from the model for both Member and USResident - since they will be inherited from User.

    We could, of course, accomplish this with a "Flat" model, but performance is not a huge concern, and by using Vertical Inheritance, we don't need to create a bunch of nullable columns with a Differentiator and a Hash column to piece the rows together to create the complete objects.

    My question is, how does Vertical Inheritance work in Data Access? Isn't this a textbook example of exactly the situation it's suppose to handle?

    Thanks,

    Mark
  7. Mark
    Mark avatar
    5 posts
    Member since:
    May 2013

    Posted 03 Jul 2014 in reply to Mark Link to this post

    Hi Boyan,

    I went back through the article you sent in greater detail. It does, in fact, look like I can do what we're looking to do via the following syntax:

    context.User.Member.USResident...

    Presumably, if context.User.Member == null, then the User is not a Member??

    Has vertical inheritance been depreciated?

    Thanks,

    Mark
  8. Boyan
    Admin
    Boyan avatar
    100 posts

    Posted 07 Jul 2014 Link to this post

    Hello Mark,

    The vertical inheritance is not deprecated but it is more often used in model first or code-only scenarios rather then in database first scenarios. You could learn in more details how vertical inheritance work from this documentation article, but basically each class of the hierarchy has its own table and the corresponding tables are linked with one-to-one associations. In order to retrieve data joins are performed. 

    This means that in the database first scenario it is possible to convert the one-to-one association to vertical inheritance hierarchy. However this is no longer required because Telerik Data Access would automatically map one-to-one associations representing the exact database schema in the domain model. 

    To compare those two approaches lets model the set-up you described both using vertical inheritance and one-to-one association using the Visual Designer and compare the resulting database scripts. Please see the attached screenshots. 
    In the first case  I have created the standard one-to-one association as described here
    In the second case I have create vertical inheritance hierarchy. For the Member and the USResident classes through the Mapping Details Editor, I have set the Inheritance Strategy to Vertical and the Descriminator Value - to Class Full Name where as the User class has Default Inheritance Strategy and Descriminator Column set to None.
    The in both scenarios, using the Update Database From Model I have created the corresponding DDL script. Please note that in both cases the scripts are equivalent. 

    To answer you question, in case of one-to-one association mapping, if a User is not a Member then User.Member would be null.  

    I hope this is helpful. Do not hesitate to contact us if you have any further questions. 

    Regards,
    Boyan
    Telerik
     
    OpenAccess ORM is now Telerik Data Access. For more information on the new names, please, check out the Telerik Product Map.
     
  9. Mark
    Mark avatar
    5 posts
    Member since:
    May 2013

    Posted 07 Jul 2014 in reply to Boyan Link to this post

    Hi Boyan,

    Great answer. Thanks.

    We got things working with the new standard one-to-one methodology, but we appreciate the attention to detail. You guys make great tools. We've been loyal users for many years, and we're excited about Data Access and just want to get the best we can out of it.

    Thanks for your help,

    Mark
Back to Top
DevCraft banner