CodeSmith Community
Your Code. Your Way. Faster!

Foreign Key Relationships

Latest post 01-26-2006 11:57 PM by bgjohnso. 16 replies.
  • 11-30-2005 2:24 PM

    • GBR
    • Top 500 Contributor
    • Joined on 11-28-2005
    • Posts 17
    • Points 530

    Foreign Key Relationships

    Hi,
     
    I'm new to .NetTiers and codesmith so I'm still finding my way.  Can someone let me know why I get two different results in the following examples?
     
    EXAMPLE 1:
     
    Tables:
    OrderHeader (Primary Key = ID)
    OrderDetail (Primary Key = OrderHeaderID, OrderDetailId)
    OrderDetail.OrderHeaderID is the Foreign Key for OrderHeader.ID
     
    The generated OrderHeader object contains a property OrderDetail.  ( this forces a one-to-one relationship )
     
    EXAMPLE 2:
     
    Tables:
    OrderHeader (Primary Key = ID)
    OrderDetail (Primary Key = ID) 
    OrderDetail.OrderHeaderID is the Foreign Key for OrderHeader.ID
    **The important thing to note: in this example the column playing the part of the Foreign key is NOT part of the primary key.
     
    The generated OrderHeader object contains a property OrderDetailCollection. ( this is what I expected to find ... a one-to-many relationship ) 
     
    Question:  Why when the Foreign Key Column is also part of the Primary Key does the Parent object NOT contain a Property that is the Child Collection object?  I was expecting to always see a Property that is a collection of the foreign key Object.
     
    I hope i explained myself well enough.
     
    Thanks...
    • Post Points: 35
  • 01-24-2006 9:19 PM In reply to

    • coolspot
    • Not Ranked
    • Joined on 01-24-2006
    • Markham, ON
    • Posts 7
    • Points 185

    Re: Foreign Key Relationships

    Did you find a solution to this problem? I am running into a similar problem with my tables...

    Does anyone know of a "fix"... or is this how .NetTiers works?

    • Post Points: 35
  • 01-25-2006 1:23 AM In reply to

    • GBR
    • Top 500 Contributor
    • Joined on 11-28-2005
    • Posts 17
    • Points 530

    Re: Foreign Key Relationships

    No.  I didn't find a solution.  My less than ideal workaround was to create a pseudo primary key.  I also posted this question that did get some feedback:

    http://community.codesmithtools.com/forums/thread/8568.aspx

     

    I'm kind-of surprised that others have not mentioned this bug/feature as it is breaks almost any database design that implements any 1-N foreign key relationships.

    If I were better versed in .NET and codesmith I'd assist in getting a solution.  So at this point I still don't know if it is 'the way it is' or if it should be a bug.  I'm guessing it's a bug ...

    • Post Points: 35
  • 01-25-2006 1:02 PM In reply to

    • tojo
    • Top 500 Contributor
    • Joined on 11-24-2005
    • Posts 14
    • Points 250

    Re: Foreign Key Relationships

    I think you're confusing netTiers with your first example, where you have two columns in your OrderDetail PK, one of which points to the the PK of OrderHeader. This is by definition a 1:1 relationship. Your second example looks more like the standard 1:n. Any reason why you can't use that?

    -- Tom

    • Post Points: 65
  • 01-25-2006 7:01 PM In reply to

    • GBR
    • Top 500 Contributor
    • Joined on 11-28-2005
    • Posts 17
    • Points 530

    Re: Foreign Key Relationships

    Why is it "by definition a 1:1 relationship"? 

    I do a better job of explaining the issue here: http://community.codesmithtools.com/forums/thread/8568.aspx  But to save you the click here is my post from that thread.

    --Cut--

    In a foreign key relationship a column of the Child table is the foreign key to the primary key in the Parent table.
     
    Usually a foreign key relationship dictates a 1-to-Many relationship.  ( One primary key in the parent table has Many children in the child table )
     
    I expect .nettiers to generate the ParentTable.ChildTableCollection property to facilitate the Parent-Child foreign key relationship.
     
    HOWEVER the ParentTable.ChildTableCollection will only get generated if the Child table foreign key column is NOT part of the child table primary key.  If is IS part of the child table primary key I only get a ParentTable.ChildTable property generated ... which would indicate it is assuming a 1-to-1 relationship ... which I don't think is correct.
     
    To put in real table terms: 
      the Student table has StudentId as the key ... 
      the StudentSubject table has StudentId and SubjectId as the primary key ...
      StudentSubject.StudentId is a ForeignKey to Student.StudentId
     
    In this example the generated Student class only has Student.StudentSubject NOT a Student.StudentSubjectCollection.  If a remove the primary key from the StudentSubjectTable the generated Student class WILL have a Student.StudentSubjectCollection.
     
    Is this the expected behaviour (and if so why)?   A Bug?    Or is my DB design / Foreign Key design flawed?

    --Cut--

     

    • Post Points: 5
  • 01-25-2006 7:21 PM In reply to

    • coolspot
    • Not Ranked
    • Joined on 01-24-2006
    • Markham, ON
    • Posts 7
    • Points 185

    Re: Foreign Key Relationships

    tojo wrote:
    I think you're confusing netTiers with your first example, where you have two columns in your OrderDetail PK, one of which points to the the PK of OrderHeader. This is by definition a 1:1 relationship. Your second example looks more like the standard 1:n. Any reason why you can't use that?

     

    How is this 1:1? Because the second table has a composite PK... it actually makes it a 1:Many relationship. Other O/R mappers map this relatioship correctly (i.e. Wilson, LLBLGen...) only .NetTiers maps it incorrectly :(

    • Post Points: 5
  • 01-25-2006 7:36 PM In reply to

    • GBR
    • Top 500 Contributor
    • Joined on 11-28-2005
    • Posts 17
    • Points 530

    Re: Foreign Key Relationships

    I've found some more information on this issue.  I did a test with the Northwind DB and just generated the Orders and OrderDetails table.  The 1-N relationship is built correctly and a OrderDetailsCollection property (1:N) is available in the Orders entity. 

    If you remove the Foreign key relationship from the ProductId column and regenerate the Orders entity now only has an OrderDetails property (1:1). 

    So... I think this changes my original problem definition to:

    If a child table column in a multi-column primary key participates in a 1:N foreign key relationship it will only be represented as a 1:N elationship in the generated Entity object only if ALL the other primary key columns in the child table also participate in foreign key relationship. 

     

    • Post Points: 35
  • 01-26-2006 10:38 AM In reply to

    • bgjohnso
    • Top 10 Contributor
    • Joined on 09-15-2005
    • Spokane, WA
    • Posts 765
    • Points 22,535

    Re: Foreign Key Relationships

    Hmmm...  Doesn't the Orders and Order Details in Northwind match situation #1?  Orders contains a single column primary key (OrderID).  Order Details has a composite PK of OrderID and ProductID.  I just generated the EntityBase for the Orders table and I get an OrderDetailCollection as expected.  What version of the templates are you using?  I have tested with the latest CVS version of the .Net 2 CTP templates and the .Net 1.1 Caribert templates....

    One other thing you could do is post your DDL scripts for the tables in question.  This will allow us to see exactly what the table, PK and FK relationships looks like.

    Ben Johnson
    ------------------------------
     Member of the .NetTiers team
     Visit http://www.nettiers.com
    ------------------------------

    • Post Points: 65
  • 01-26-2006 12:31 PM In reply to

    • coolspot
    • Not Ranked
    • Joined on 01-24-2006
    • Markham, ON
    • Posts 7
    • Points 185

    Re: Foreign Key Relationships

    I'm using 0.92 - the one listed on .NetTier's website. Is that the latest stable version?
    • Post Points: 35
  • 01-26-2006 12:47 PM In reply to

    • bgjohnso
    • Top 10 Contributor
    • Joined on 09-15-2005
    • Spokane, WA
    • Posts 765
    • Points 22,535

    Re: Foreign Key Relationships

    If you are using .Net 1.1, then you should be using 0.9.2 (Caribert).  If you are using .Net 2.0, you should use the CTP version, which uses .Net 2.0 features (generics, nullable types, etc).  Regardless of which version you are using, I would strongly recommend that you download the latest nightly build or use a CVS tool (I use TortoiseCVS) to get the latest code bits.  The team makes fairly regular updates to the templates to fix issues that are found in the templates.  If you run into a bug, you should get the latest code to see if it has been resolved.  "Stable" is a bit of a tricky word...

    Ben Johnson
    ------------------------------
     Member of the .NetTiers team
     Visit http://www.nettiers.com
    ------------------------------

    • Post Points: 5
  • 01-26-2006 7:06 PM In reply to

    • GBR
    • Top 500 Contributor
    • Joined on 11-28-2005
    • Posts 17
    • Points 530

    Re: Foreign Key Relationships

    Yes.  You are correct.  However in my last post I outlined new information I found which I think pin-points the issue.  In summary: 

    "If a child table column in a multi-column primary key participates in a 1:N foreign key relationship it will only be represented as a 1:N elationship in the generated Entity object only if ALL the other primary key columns in the child table also participate in foreign key relationship. " 

    Hmmm...  Doesn't the Orders and Order Details in Northwind match situation #1?  Orders contains a single column primary key (OrderID).  Order Details has a composite PK of OrderID and ProductID.  I just generated the EntityBase for the Orders table and I get an OrderDetailCollection as expected.  What version of the templates are you using?  I have tested with the latest CVS version of the .Net 2 CTP templates and the .Net 1.1 Caribert templates....

    One other thing you could do is post your DDL scripts for the tables in question.  This will allow us to see exactly what the table, PK and FK relationships looks like.


    Ben Johnson
    ------------------------------
     Member of the .NetTiers team
     Visit http://www.nettiers.com
    ------------------------------

     

     

    • Post Points: 35
  • 01-26-2006 7:29 PM In reply to

    • bgjohnso
    • Top 10 Contributor
    • Joined on 09-15-2005
    • Spokane, WA
    • Posts 765
    • Points 22,535

    Re: Foreign Key Relationships

    Bear with me...  I still don't understand.  I have created a simple master child scenario (DDL below):

    CREATE TABLE [dbo].[OrderMaster] (
     [ID] [char] (10)  NOT NULL ,
     [OrderName] [varchar] (50)  NOT NULL
    ) ON [PRIMARY]
    GO

    ALTER TABLE [dbo].[OrderMaster] WITH NOCHECK ADD
     CONSTRAINT [PK_OrderMaster] PRIMARY KEY CLUSTERED
     (
      [ID]
     ) ON [PRIMARY]
    GO

    CREATE TABLE [dbo].[OrderDetail] (
     [OrderLineNum] [int] NOT NULL ,
     [OrderID] [char] (10)  NOT NULL ,
     [LineAmount] [float] NOT NULL
    ) ON [PRIMARY]
    GO

    ALTER TABLE [dbo].[OrderDetail] WITH NOCHECK ADD
     CONSTRAINT [PK_OrderDetail] PRIMARY KEY CLUSTERED
     (
      [OrderLineNum] ,
      [OrderID]
     ) ON [PRIMARY]
    GO

    ALTER TABLE [dbo].[OrderDetail] WITH NOCHECK ADD
     CONSTRAINT [FK_OrderDetail_OrderMaster] FOREIGN KEY
     (
      [OrderID]
     ) REFERENCES [dbo].[OrderMaster] (
      [ID]
     ) ON DELETE CASCADE ON UPDATE CASCADE
    GO

    Very simple, but I think it matches the scenario that you have described.  The OrderDetail table has a composite primary key, and only one of the columns participates in a FK relationship.  When I generate my classes for this scenario, I get the OrderDetailCollection property as expected.  Am I missing something?  Maybe I'm just thick in the head...

    Ben Johnson
    ------------------------------
     Member of the .NetTiers team
     Visit http://www.nettiers.com
    ------------------------------

    • Post Points: 35
  • 01-26-2006 7:50 PM In reply to

    • coolspot
    • Not Ranked
    • Joined on 01-24-2006
    • Markham, ON
    • Posts 7
    • Points 185

    Re: Foreign Key Relationships

    Interesting... I wonder why it works for you... and not me!

     

    I guess I need to do more testing on my end... should I post a DDL?

    • Post Points: 35
  • 01-26-2006 7:53 PM In reply to

    • bgjohnso
    • Top 10 Contributor
    • Joined on 09-15-2005
    • Spokane, WA
    • Posts 765
    • Points 22,535

    Re: Foreign Key Relationships

    That would help...  Does it work if you use the Orders and Order Details tables in Northwind?

    Ben Johnson
    ------------------------------
     Member of the .NetTiers team
     Visit http://www.nettiers.com
    ------------------------------

    • Post Points: 60
  • 01-26-2006 9:53 PM In reply to

    • GBR
    • Top 500 Contributor
    • Joined on 11-28-2005
    • Posts 17
    • Points 530

    Re: Foreign Key Relationships

    Ben,  You are right on the money.  Your understanding of the issue is correct.  In all my parent-child table relationships the 1:N mapping is not represented in .nettiers generated code.

    I did some more digging:  I think we are getting closer to the issue.  If I modify your schema and re-order the sequence of the PK columns you no longer get the a 1:N OrderDetailCollection in the OrderMaster entity object.  You get a 1:1 mapping.

    CREATE TABLE [dbo].[OrderMaster] (
     [ID] [char] (10)  NOT NULL ,
     [OrderName] [varchar] (50)  NOT NULL
    ) ON [PRIMARY]
    GO

    ALTER TABLE [dbo].[OrderMaster] WITH NOCHECK ADD
     CONSTRAINT [PK_OrderMaster] PRIMARY KEY CLUSTERED
     (
      [ID]
     ) ON [PRIMARY]
    GO

    CREATE TABLE [dbo].[OrderDetail] (
     [OrderLineNum] [int] NOT NULL ,
     [OrderID] [char] (10)  NOT NULL ,
     [LineAmount] [float] NOT NULL
    ) ON [PRIMARY]
    GO

    ALTER TABLE [dbo].[OrderDetail] WITH NOCHECK ADD
     CONSTRAINT [PK_OrderDetail] PRIMARY KEY CLUSTERED
     (
      [OrderID],
      [OrderLineNum]

     ) ON [PRIMARY]
    GO

    ALTER TABLE [dbo].[OrderDetail] WITH NOCHECK ADD
     CONSTRAINT [FK_OrderDetail_OrderMaster] FOREIGN KEY
     (
      [OrderID]
     ) REFERENCES [dbo].[OrderMaster] (
      [ID]
     ) ON DELETE CASCADE ON UPDATE CASCADE
    GO

     

    This results in the the following code in the OrderMaster

    private OrderDetail _OrderDetail = new OrderDetail();

    /// <summary>

    /// Holds a OrderDetail object

    /// which is related to this object through the relation FK_OrderDetail_OrderMaster

    /// </summary>

    public OrderDetail OrderDetail

    {

    get { return _OrderDetail; }

    set { _OrderDetail = value; }

    }


    • Post Points: 5
Page 1 of 2 (17 items) 1 2 Next > | RSS
Copyright © 2008 CodeSmith Tools, LLC
Powered by Community Server (Commercial Edition), by Telligent Systems