两个具有相同导航属性的外键?

时间:2014-03-09 10:28:44

标签: c# entity-framework orm entity-framework-4 entity-framework-6

我是Entity Framework的新手,所以我对此并不了解。目前我正在研究My College Project,在那个项目中我遇到了一个问题,我有两个外键引用另一个表中的Same列。我怎么能处理这种情况。

是否需要为每个外键创建导航属性。如果我为ContactId创建另一个Navigaton属性,则需要在User类中创建另一个导航属性,如:

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

请告诉我解决这个问题的最佳方法。我正在使用Entity Framework 6。

以下是我的模型类:

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

2 个答案:

答案 0 :(得分:1)

  

是否需要为每个外键创建导航属性?

是,或更确切地说:每个关系至少需要一个导航属性。 “至少一个”表示您可以决定要将导航属性添加到两个实体中的哪一个。如果您经常想要从实体A导航到实体B,或者反过来,它通常取决于应用程序中最常见的用例。如果需要,可以将导航属性添加到两个实体,但不需要。

在你的模型中,你显然有两个(一对多)关系。如果要在两个实体中公开导航属性,则需要四个导航属性 - 重要的是! - 您必须为关系定义哪些导航属性形成一对(请参阅以下代码段中的[InverseProperty]属性)。

使用数据注释,它会这样:

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

如果您不想要BlockedContacts集合,您可以将[InverseProperty("BlockedContacts")]导航属性中的Contact属性删除。

答案 1 :(得分:0)

您可以使用属性 ForeignKey 来解决您的问题。 ForeignKey 用于配对导航属性和外键属性.FK数据注释与外键属性和FK与导航属性没有区别。但是,以下代码将创建两个具有不同名称的外键。

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