代码优先生成额外的列
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; }
}
我有一组玩家通过 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; }
}