代码优先生成额外的列

Code first Generating Extra Columns

我有一组玩家通过 FriendLinker table 链接在一起。

table 将两个玩家链接在一起(在本例中,它的玩家->朋友)。我的播放器设置如下:

public class Player
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key, Column(Order=0)]
    public Guid PlayerId { get; set; }

    public virtual ICollection<FriendLinker> Friends { get; set; }

    [Required]
    public string Password { get; set; } //Will be switched to byte[] for hash

    [MaxLength(100)]
    [Index(IsUnique = true)]
    public string Username { get; set; }
}

链接器table是这样设置的:

public class FriendLinker
{
    [Key]
    public int FriendLinkerId { get; set; }

    [Required]
    public Player Player { get; set; }

    [Required]
    public Player Friend { get; set; }
}

但是,这会生成以下迁移:

CreateTable(
"dbo.FriendLinkers",
c => new
{
     FriendLinkerId = c.Int(nullable: false, identity: true),
     Player_PlayerId = c.Guid(),
     Friend_PlayerId = c.Guid(nullable: false),
     Player_PlayerId1 = c.Guid(nullable: false),
})
.PrimaryKey(t => t.FriendLinkerId)
.ForeignKey("dbo.Players", t => t.Player_PlayerId)
.ForeignKey("dbo.Players", t => t.Friend_PlayerId, cascadeDelete: false)
.ForeignKey("dbo.Players", t => t.Player_PlayerId1, cascadeDelete: false)
.Index(t => t.Player_PlayerId)
.Index(t => t.Friend_PlayerId)
.Index(t => t.Player_PlayerId1);

结果创建了一个额外的列 Player_PlayerId1。当我执行 player.Friends.add(..) 时,playerId 被插入到 PlayerId1.

我应该怎么做才能防止生成额外的列 PlayerId1

它发生了,因为 FriendLinker class 有两个 link 到 Player class,但是 Player class只有一个 link 并且 EF 对此有点困惑,因此出现了额外的列 Player_PlayerId1,该列正好 linked 为 Player(ICollection 属性,这就是为什么:当我执行 player.Friends.add(..) 时,playerId 被插入到 PlayerId1.)。您指定的另外两列被视为隐式 linked 到 Player class。您可以通过在 Player class 声明中向 FriendLinker class 添加第二个 link 来修复它,并指定此 link 将用于哪些具体属性通过 InverseProperty 属性的构造函数参数关联:

public class Player
{
    [InverseProperty("Player")]
    public virtual ICollection<FriendLinker> Players { get; set; }

    [InverseProperty("Friend")]
    public virtual ICollection<FriendLinker> Friends { get; set; }

    [Required]
    public string Password { get; set; } //Will be switched to byte[] for hash

    [MaxLength(100)]
    [Index(IsUnique = true)]
    public string Username { get; set; }
}