Entity Framework 4.3代码优先多对多关系使用相同表

33

我有一个模型:

public class User
{
    [Key]
    public long UserId { get; set; }

    [Required]
    public String Nickname { get; set; }

    public virtual ICollection<Town> Residencies { get; set; }

    public virtual ICollection<Town> Mayorships { get; set; }
}

并且

public class Town
{
    [Key]
    public long TownId { get; set; }

    [Required]
    public String Name { get; set; }

    public virtual ICollection<User> Residents { get; set; }
    public virtual ICollection<User> Mayors { get; set; }
}

我希望EF能够使用自动创建的TownResidents和TownMayors表来创建两个多对多关系。但是我无法找到必要的约定或显式注释来获得这个结果。

相反,我在Town表中得到了两个FK UserIds,并且在User表中得到了两个FK TownIds。

有什么办法让EF将它们视为两个多对多关系吗?

谢谢。

1个回答

35

嗯,EF没有某种单词和语法识别算法,该算法需要确定您(可能)想要User.ResidenciesTown.Residents形成一对导航属性,以及User.MayorshipsTown.Mayors形成第二对。因此,它假定您有四个一对多关系,并且每个导航属性都属于其中一个关系。(这就是您在数据库表中看到的四个外键的原因。)

这种标准假设不是您想要的,因此您必须明确定义关系以覆盖此标准约定:

可以使用数据注释:

public class User
{
    [Key]
    public long UserId { get; set; }

    [Required]
    public String Nickname { get; set; }

    [InverseProperty("Residents")]
    public virtual ICollection<Town> Residencies { get; set; }

    [InverseProperty("Mayors")]
    public virtual ICollection<Town> Mayorships { get; set; }
}

或者使用流畅的API:

modelBuilder.Entity<User>()
    .HasMany(u => u.Residencies)
    .WithMany(t => t.Residents)
    .Map(x =>
    {
        x.MapLeftKey("UserId");
        x.MapRightKey("TownId");
        x.ToTable("TownResidents");
    });

modelBuilder.Entity<User>()
    .HasMany(u => u.Mayorships)
    .WithMany(t => t.Mayors)
    .Map(x =>
    {
        x.MapLeftKey("UserId");
        x.MapRightKey("TownId");
        x.ToTable("TownMayors");
    });

流畅的API具有优势,您可以控制链接表的名称(以及键列的名称)。您无法使用数据注释定义这些名称。


谢谢。我尝试了两种方法,它们都有效,但像你说的那样,流畅方法让你控制表名,所以我更喜欢那种方法。再次感谢。 - Sean
地图部分不是必需的。您的流畅API代码可以在没有它的情况下完成工作。 - ozgur

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接