C# 如何创建指向同一唯一字符串列的两个字符串外键?

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

我有一个实体“Player”,它的“Guid”属性类型为string,具有唯一约束

我有一个“PlayerData”实体,它的属性为string类型的“PlayerGuid”、“OpponentPlayerGuid”

如何使用EF Core确保PlayerGuid和OpponentPlayerGuid属性只接受Player.Guid属性中的值

我尝试过各种方法,从stackoverflow上可能有5个以上的不同答案,但没有一个能帮助我解决这个问题

PlayerData实体

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是主键候选项,如果将其用作主键,设计将更简单。