Two foreign keys with same Navigation Property?

c# entity-framework entity-framework-4 entity-framework-6 orm

Question

Entity Framework is something I'm new to, so I don't know much about it. As I work on my college project at the moment, I've run across a dilemma where two foreign keys point to the same column in a different table. How do I approach this problem.

Is the creation of Navigation Properties for Each Foreign Key Required? Additionally, if I add another navigation property for ContactId, I'll need to add another navigation property to the User class, such as:

public virtual ICollection<BlockedUser> SomePropertyName { get; set; }

Please advise me on the most effective solution to this issue. Entity Framework 6 is what I'm using.

Following are my sample classes:

public class BlockedUser
{
    // User Foreign Key
    public int UserId { get; set; }               // Composite Primary Key

    // User Foreign key
    public int ContactId { get; set; }            // Composite Primary Key

    // User Navigation Property
    public virtual User User { get; set; }
}

public class User
{
    public int UserId { get; set; }  // Primary key
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }

    // BlockedUser Navigation Property
    public virtual ICollection<BlockedUser> BlockedUsers { get; set; }
}
1
1
3/9/2014 11:38:03 AM

Accepted Answer

Is it necessary to create Navigation Property for Every Foreign key?

Yes, or more specifically: For every relationship, you require at least one navigation property. It's up to you to choose which of the two entities you want to add the navigation attribute to when it says "at least one." In most circumstances, whether you frequently wish to move from entity A to entity B or the other way around depends on the most frequent use cases in your application. Although it is optional, you can add the navigation properties to both entities.

You appear to have two (one-to-many) relationships in your model. Four navigation properties are required if you want to expose navigation properties in both entities, and - crucially - you must specify which navigation properties make up a pair for a relationship (see the[InverseProperty] attribute in the ensuing snippet of code).

This is what we would like from data annotations:

public class BlockedUser
{
    [Key, ForeignKey("User"), Column(Order = 1)]
    public int UserId { get; set; }

    [Key, ForeignKey("Contact"), Column(Order = 2)]
    public int ContactId { get; set; }

    [InverseProperty("BlockedUsers")]
    public virtual User User { get; set; }

    [InverseProperty("BlockedContacts")]
    public virtual User Contact { get; set; }
}

public class User
{
    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }

    public virtual ICollection<BlockedUser> BlockedUsers { get; set; }
    public virtual ICollection<BlockedUser> BlockedContacts { get; set; }
}

Unless you want theBlockedContacts You may probably just remove it from the collection and the[InverseProperty("BlockedContacts")] characteristic coming fromContact additionally a navigation property

1
3/9/2014 4:43:21 PM

Popular Answer

You could resolve your issue by using attribute ForeignKey. Foreign key property and navigation property are paired using the notation ForeignKey. The Foreign Key data annotation and the Foreign Key with Navigation Properties have no differences. The code below, however, will produce two foreign keys with distinct names.

public class BlockedUser
{
// User Foreign Key
[ForeignKey("UserId")]
public int UserId { get; set; }               // Composite Primary Key

// User Foreign key
[ForeignKey("BlockedUser_User")]
public int ContactId { get; set; }            // Composite Primary Key

// User Navigation Property
public virtual User User { get; set; }
}

public class User
{
public int UserId { get; set; }  // Primary key
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }

// BlockedUser Navigation Property
public virtual ICollection<BlockedUser> BlockedUsers { get; set; }
}


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