实体框架4.3代码首先使用相同的表多次多对多

Sea*_*ean 31 c# entity-framework ef-code-first entity-framework-4.3

我有一个像这样的模特

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; }
}
Run Code Online (Sandbox Code Playgroud)

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; }
}
Run Code Online (Sandbox Code Playgroud)

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

相反,我在Town表中获得两个FK UserIds,在User表中获得两个FK TownIds.

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

谢谢

Sla*_*uma 32

好吧,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; }
}
Run Code Online (Sandbox Code Playgroud)

或者使用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");
    });
Run Code Online (Sandbox Code Playgroud)

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