C# 如何创建指向同一唯一字符串列的两个字符串外键?
我有一个实体“Player”,它的“Guid”属性类型为string,具有唯一约束 我有一个“PlayerData”实体,它的属性为string类型的“PlayerGuid”、“OpponentPlayerGuid” 如何使用EF Core确保PlayerGuid和OpponentPlayerGuid属性只接受Player.Guid属性中的值 我尝试过各种方法,从stackoverflow上可能有5个以上的不同答案,但没有一个能帮助我解决这个问题 PlayerData实体C# 如何创建指向同一唯一字符串列的两个字符串外键?,c#,entity-framework-core,C#,Entity Framework Core,我有一个实体“Player”,它的“Guid”属性类型为string,具有唯一约束 我有一个“PlayerData”实体,它的属性为string类型的“PlayerGuid”、“OpponentPlayerGuid” 如何使用EF Core确保PlayerGuid和OpponentPlayerGuid属性只接受Player.Guid属性中的值 我尝试过各种方法,从stackoverflow上可能有5个以上的不同答案,但没有一个能帮助我解决这个问题 PlayerData实体 public clas
public class PlayerData
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int AttackLevel { get; set; } = 0;
public int DefenseLevel { get; set; } = 0;
[InverseProperty("Guid")]
public string PlayerGuid { get; set; }
public Player Player { get; set; }
//[ForeignKey("OpponentPlayerGuid")]
//public string OpponentPlayerGuid { get; set; }
public int WinStreak { get; set; } = 0;
public double Armor { get; set; }
public double Health { get; set; }
public bool Acted { get; set; }
public ActionType LastAction { get; set; }
}
玩家实体
public class Player
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[ForeignKey("SessionId")]
public int? SessionId { get; set; }
public Session Session { get; set; }
[Required,MaxLength(36)]
public string Guid { get; set; }
public DateTime? BanTime { get; set; }
public List<PlayerData> PlayerDatas { get; set; }
}
公共类播放器
{
[关键]
[数据库生成(DatabaseGeneratedOption.Identity)]
公共int Id{get;set;}
[外键(“SessionId”)]
public int?SessionId{get;set;}
公共会话会话{get;set;}
[必需,最大长度(36)]
公共字符串Guid{get;set;}
公共日期时间?BanTime{get;set;}
公共列表播放数据{get;set;}
}
您需要在guid上指定备用键。然后配置它的外键。通过使用fluentapi来实现。此处的用法示例: 在DbContext类中:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<PlayerData>()
.HasOne(e => e.Player)
.WithMany() // If its a one to one relationsship, specify 'WithOne()' here
.HasForeignKey(e => e.PlayerGuid)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<PlayerData>()
.HasOne(e => e.OpponentPlayer)
.WithMany()
.HasForeignKey(e => e.OpponentPlayerGuid)
.OnDelete(DeleteBehavior.Restrict);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasOne(e=>e.Player)
.WithMany()//如果是一对一关系,请在此处指定“WithOne()”
.HasForeignKey(e=>e.PlayerGuid)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity()
.HasOne(e=>e.OpponentPlayer)
.有很多
.HasForeignKey(e=>e.OpponentPlayerGuid)
.OnDelete(DeleteBehavior.Restrict);
}
另请注意:您应该使用BCL提供的值类型
Guid
,而不是字符串。这样,您的ID将始终是Guid。如果您不介意我问一下,您不使用ID引用玩家和对手有什么具体原因吗?然后您可以使用外键引用播放器表。Guid是用于跟踪数据库条目的字段/属性。我认为PlayerGuid是主键候选项,如果将其用作主键,设计将更简单。