This is a migrated thread and some comments may be shown as answers.

Navigation Property vs Id Field

6 Answers 108 Views
Development (API, general questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Chuck
Top achievements
Rank 1
Chuck asked on 12 Apr 2012, 07:37 PM
Does it make any difference to use one or the other?  For example:

Parent: Id
Child: Id, ParentId  (navigation property Parent created automatically)
 
myChild.Parent = myParent
 
vs.
 
myChild.ParentId = myParent.Id

6 Answers, 1 is accepted

Sort by
0
Accepted
Viktor Zhivkov
Telerik team
answered on 17 Apr 2012, 03:53 PM
Hello Chuck,

In short: using the navigation property is the preferred method of setting relationship values.  

There is one important difference between these two approaches - there is no convenient way to handle creation of the whole object sub-tree using the foreign key property.

To illustrate the case imagine the following scenario:
class Customer
{
    int Id;
    string FirstName;
    string LastName;
    int AddressId;
    Address Address;
}
 
class Address
{
    int Id;
    string City;
    string Street;
}

When you create a new customer you should create a new instance of address too.

If you use the navigation property setter your code should do these steps:
  1. Create new Customer instance, add it to the context.
  2. Create new Address instance, set newly created customer's address navigation property to the new address instance and add the address instance to the context.
  3. Call SaveChanges method of the context

If you use the "raw" foreign key property setter the code should include the following steps:
  1. Create new Address instance, add it to the context.
  2. Call SaveChanges method of the context in order to get the ID of the new address instance.
  3. Create new Customer instance, add it to the context.
  4. Set the customer's AddressId to the ID of the address instance.
  5. Call SaveChanges method of the context.

As you see using the "raw" foreign key property in this scenario will make the things a bit complicated because you do not know the ID of the newly created address instance and have to obtain it first before assigning in to the customer. If you use the navigation property the issue is solved easily using simple assignment - OpenAccess will take care of the plumbing required.

In case you are linking a look-up table or a record that is already loaded in OpenAccess context you can use either one of the approaches.

Let us know if you need any clarifications.
 
Kind regards,
Viktor Zhivkov
the Telerik team
Telerik OpenAccess ORM Q1 2012 release is here! Check out what's new or download a free trial >>
0
Chuck
Top achievements
Rank 1
answered on 17 Apr 2012, 04:04 PM
That answers my question.  Thank you very much.
0
Accepted
IT-Als
Top achievements
Rank 1
answered on 18 Apr 2012, 05:59 AM
Hi Chuck,

As an addition to the answer from Viktor you should be aware that when you use the "raw" way of setting the id, you issue a call to SaveChanges() twice. Thus you actually do a database Commit twice.
So lets assume that the first creation of the Address is done without errors, but the second creation of the Customer goes wrong. Doing so it doesn't matter if you do a rollback, since you already Committed the first change (the Address)... so you will have an Address instance hanging around forever.

When doing it the "navigation" way (the right way in my opinion) you only issue one call to SaveChanges thus only one database Commit...so if anything goes wrong you can just rollback the changes and you will be at the point where you started your transaction again.
I use a pattern like the below for doing manipulations on the model:

try
{
    // Explicit start the transaction if it has not been started yet

   // Do your model manipulation

  // Call SaveChanges (Commit)

}
catch (Exception e)
{
   // Rollback changes
}

Regards

Henrik
0
Chuck
Top achievements
Rank 1
answered on 18 Apr 2012, 01:17 PM
Viktor & Henrik,

So it sounds like the main concern is when you are creating a relationship between two or more "new" objects.

Good to know, and this is what I've been doing.

However, in another scenario I may store a key value for a preexisting object in session state or view state and not persist the entire object between postbacks.  In this case it sounds like it is valid to create a new related object (parent or child - depending on the IsManaged property), and then set up the relationship using just the foreign key value I had previously stored.  I am not forced to make a round trip to the database to first create an instance of the original object in order to make sure the relation is successful.

If this is not correct, please let me know.  I wanted to make sure there wouldn't be any unanticipated consequences.
0
Viktor Zhivkov
Telerik team
answered on 20 Apr 2012, 01:25 PM
Hello Chuck,

If you already have the Id of the reference object, it is OK to set the foreign key Id property.

One important consideration while using this approach is that if you try to access the navigation property later, the referenced object will be loaded from the database (with a query or from the OpenAccess cache if present).

You may also have to take extra care to avoid/handle errors caused by incorrect/missing foreign key Ids.

Kind regards,
Viktor Zhivkov
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the OpenAccess ORM, subscribe to their blog feed now.
0
Chuck
Top achievements
Rank 1
answered on 20 Apr 2012, 01:28 PM
Thank you again!  I speak highly of your support & tools.
Tags
Development (API, general questions)
Asked by
Chuck
Top achievements
Rank 1
Answers by
Viktor Zhivkov
Telerik team
Chuck
Top achievements
Rank 1
IT-Als
Top achievements
Rank 1
Share this question
or