0

Let's say I have the following classes, auto generated by Entity Framework, that have an association:

public class Parent() 
{
    public int ParentID { get; set; } // PK
    public int ChildID { get; set; } // FK
    public string Description { get; set; } 
    public Child Child { get; set; } // Navigation property
}

public class Child() 
{
    public int ChildID { get; set; } // PK
    public Parent Parent { get; set; } // Navigation property
}

enter image description here

As you can see, the Parent class contains a foreign key property to the Child class.

Now, let's say I want to retrieve some data from my database with LINQ. What I would do is create a custom class (model) so that I don't have to work with the auto generated classes (I can easily add more properties, methods,...).

public class ChildModel() 
{
    public int ChildID { get; set; }
    // More properties/methods
}

When creating the ParentModel class, I have two ways of creating this class:

A class with both the property ChildID and a navigation property Child.

public class ParentModel() 
{
    public int ParentID { get; set; }
    public int ChildID { get; set; } 
    public ChildModel Child { get; set; }
}

Or a class with only a navigation property Child and no ChildID property.

public class ParentModel() 
{
    public int ParentID { get; set; } 
    public ChildModel Child { get; set; }
}

With the second method, I always have to create an extra class when I only need the ChildID, with the second method I don't have to. But when I do create the ChildModel, I have to initialize both ChildIDs so that I don't run into any problems later.

What would be the best way to create my model classes? With or without the foreign key? Are there any advantages/disadvantages when using one of the two methods described above?

  • I may be missing something but wouldn't you want to use a collection of children for the property in the Parent class since a parent can have more than one child? So public List<ChildModel> Children { get; set; } – webworm Apr 12 '17 at 15:58
2

Using both childId and Child property seems to be the worst option because of potential mistakes / inconsistencies.

Having only the Navigation property seems best option for several reasons:

  1. If the relationship is optional you have a clear indication that there is no child by setting the property to null. In case you have only childId, you need to set it to some magic number like -1 or 0, which is less elegant I suppose, or make it int? type which isn't a better solution either.

  2. With Navigation property you can implement several features like automatic lazy loading.

  3. Your objects stay abstract to the actual storage and relationship implementation.

| improve this answer | |
1

Microsoft recommends using both, although your example looks like you have the foreign key on the wrong class. I would have expected the Child class to be dependant on the Parent. The parent class doesn't need the foreign key because it's not dependant on its children.

To quote Microsoft: In addition to navigation properties, we recommend that you include foreign key properties on the types that represent dependent objects.

https://msdn.microsoft.com/en-nz/data/jj679962.aspx

public class ParentModel() 
{
    public int ParentID { get; set; }

    //navigation property
    public ChildModel Child { get; set; }
}      

public class ChildModel() 
{
    public int ChildID { get; set; }
    // More properties/methods

    //foreign key
    public int ParentID { get; set; }
    //navigation property
    public ParentModel Parent { get; set; }

}

| improve this answer | |
  • Why Microsoft recommends that? Another question rising is, are the foreign-key properties initialized even if the entity itself uses lazy loading? Then there was a real benefit of also adding the fk property. – Tim Schmelter Jan 28 '19 at 9:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.