Two foreign keys with same Navigation Property?

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

Question

I am new to Entity Framework so I don't know much about it. Currently I am working on My College Project, in that Project I came across a problem where I have two foreign keys refers to the Same column in another table. how can I handle this situation.

Is it necessary to create Navigation Property for Every Foreign key. And if I create another Navigaton property for ContactId then it is necessary to create another Navigation Property in User class like:

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

please tell me the best way to overcome this problem. I am using Entity Framework 6.

Here are My Model 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 precisely: You need at least one navigation property for every relationship. "At least one" means that you can decide which of the two entities you want to add the navigation property to. It normally depends on the most common use cases in your application if you often want to navigate from entity A to entity B or the other way around. If you want, you can add the navigation properties to both entities but you don't need to.

In your model you apparently have two (one-to-many) relationships. If you want to expose navigation properties in both entities you would need four navigation property and - important! - you have to define which navigation properties form a pair for a relationship (see the [InverseProperty] attribute in the following code snippet).

With data annotations it would like this:

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; }
}

If you don't want the BlockedContacts collection you can probably just remove it and the [InverseProperty("BlockedContacts")] attribute from the Contact navigation property as well.

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

Popular Answer

You could use attribute ForeignKey to solve your problem. ForeignKey is used to pair navigation property and foreign key property.There is no difference between FK data annotation with Foreign Key property and FK with Navigation Properties. However, the following code will create two foreign keys with different name.

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