what is difference between inverse property and foreign key in entity framework?

c# entity-framework

Question

I was aware that when there are many associations between classes, inverse properties are employed. However, since all of these are utilised to define relationships, I am unsure of the difference between inverse property and foreign key property.

public class PrivilegeToDbOperationTypeMap : BaseEntity
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity), Column(Order = 0)]
    public int PrivilegeToDbOperationTypeMapId { get; set; }

    [ForeignKey("privilegeLookup"), Column(Order = 1)]
    [Index("IX_PrivilegeLookupId_DbOperationLookupId", 1, IsUnique = true)]
    public int PrivilegeLookupId { get; set; }

    [ForeignKey("dbOperationTypeLookup"), Column(Order = 2)]
    [Index("IX_PrivilegeLookupId_DbOperationLookupId", 2, IsUnique = true)]
    public int DbOperationLookupId { get; set; }

    #region Navigation Properties

    public PrivilegeLookup privilegeLookup { get; set; }

    public DbOperationTypeLookup dbOperationTypeLookup { get; set; }

    [InverseProperty("privilegeToDbOperationTypeMap")]
    public ICollection<RoleToPrivilegeDbOperationTypeMap> roleToPrivilegeDbOperationTypeMaps { get; set; }

    #endregion Navigation Properties
}
1
14
11/8/2016 6:47:31 AM

Accepted Answer

Using the foreign key property, you can:

  1. Name the navigation property that is connected to the specified foreign key property.

    // this is foreign key property with related "privilegeLookup" navigation property. Database column name will be PrivilegeLookupId
    [ForeignKey("privilegeLookup"), Column(Order = 1)]       
    public int PrivilegeLookupId { get; set; }
    // this is related navigation property
    public PrivilegeLookup privilegeLookup { get; set; }
    
  2. OR provide the foreign key property's name for the specified navigation property:

    // this is foreign key property
    public int PrivilegeLookupId { get; set; }
    // this is navigation property with related foreign key property
    [ForeignKey("PrivilegeLookupId")]  
    public PrivilegeLookup privilegeLookup { get; set; }
    

When the standard EF code-first standards do not apply or apply in an unsuitable manner for you, it might be helpful. You may see a list of EF code-first conventions at Here.

When you need to specify that a navigation property in class A is connected to the same foreign key as another navigation property in class B, you should use the inverse property attribute. For instance:

public class Student
{
    public int StudentID { get; set; }

    public Standard CurrentStandard { get; set; }
    public Standard PreviousStandard { get; set; }
}

public class Standard
{    
    public int StandardId { get; set; }

    public ICollection<Student> CurrentStudents { get; set; }
    public ICollection<Student> PreviousStudents { get; set; }   
}

Each of the two classes in this instance has two navigation attributes. CurrentStandardId and PreviousStandardId are likely the names of the two foreign keys we want to have in table Student, and the navigation attributes of class Standard are also connected to these foreign keys (one to many relationship). Without further instruction, EF won't recognise this in this scenario and will instead generate 4 foreign keys. We must utilise the inverse property attribute to direct it:

public class Standard
{
    public int StandardId { get; set; }

    // reference to the name of another navigation property in class Student
    [InverseProperty("CurrentStandard")]
    public ICollection<Student> CurrentStudents { get; set; }

    // reference to the name of another navigation property in class Student
    [InverseProperty("PreviousStandard")]
    public ICollection<Student> PreviousStudents { get; set; }   
}

Now that EF is aware of our goals, just two foreign keys will be created, although with poor names. Using the foreign key property, we can easily modify the names of the columns:

public class Student 
{
    public int StudentID { get; set; }

    public int CurrentStandardId { get; set; }
    public int PreviousStandardId { get; set; }

    [ForeignKey("CurrentStandardId")]
    public Standard CurrentStandard { get; set; }

    [ForeignKey("PreviousStandardId")]
    public Standard PreviousStandard { get; set; }
}

In conclusion, EF can infer a lot of information from coding standards. However, if it is unable to (for instance, if there are two foreign keys in the same class), you must assist it by utilising the properties from your query.

21
11/8/2016 8:08:19 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow