31

我有一个模型

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 UserId,在 User 表中获得了两个 FK TownId。

任何想法如何让 EF 在两个多对多关系中看到这些?

谢谢

4

1 回答 1

34

好吧,EF 没有某种单词和语法识别算法来识别您(可能)需要它User.ResidenciesTown.Residents形成一对导航属性并User.Mayorships形成Town.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; }
}

或者使用 Fluent 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");
    });

Fluent API 的优点是您可以控制链接表的名称(以及键列名称)。您不能使用数据注释定义这些名称。

于 2012-02-24T22:36:40.497 回答