这是什么类型的关系以及如何在 .NET Core(EFCore、FluentAPI)中实现它?

What type of relationship is this and how to implement it in .NET Core (EFCore, FluentAPI)?

我遇到的问题很简单,但我的脑子不灵了。对不起,如果我的问题很愚蠢,但我不太擅长数据库(我也不擅长 EFCore)。

我想要以下 tables:

CV:带 ID 和 Name/Title(字符串)

技能:带ID和Name/Title(字符串)

SkillsCV:带有 ID、CvID(CV 中记录的外键)、SkillID(Skills 中记录的外键)

我不想在 CV 和技能 table 中有指向 SkillsCV 的外键。可能吗?在 .NET Core 中是否可行,更重要的是在 Fluent API 中可行吗? 我对 FluentAPI 做了一个小研究,一对一关系的两端都有外键。这个有必要吗?顺便说一句,这是一对一的关系,对吧?我不想让一方知道另一方。这就是所谓的0比1,还是完全不同的东西?我真的很困惑。

所以我在 FluentAPI 中看到的一对一关系,我需要以下代码:

modelBuilder.Entity<Skill>()
        .HasOne(skill => skill.SkillCV) // but I don't have a SkillCV object in Skill model
        .WithOne(skillCV => skillCV.Skill) // I have skillCV.Skill
        .HasForeignKey<SkillCV>(skillCV => skillCV.SkillID); // I have this foreign key in skillCV as well

但我不想在技能 table 中有一个对象(或外键)(因为我不想在 CVs table 中有这样的对象)。 这可能吗?我肯定做错了什么。 你能帮我找出错误吗(如果有的话)?

如果您知道更好的方法,请分享。提前致谢!

编辑:我要创建的内容的快速示例:

简历Table:

身份证、姓名

1 "CV1"

2 "CV2"

3 "CV3"

技能Table:

身份证、姓名

1 "C#"

2 "Java"

3 "Python"

SkillsCV Table:

ID、CvID、SkillID

1 1 1

2 1 3

3 2 1

这是解决这个问题的好方法吗?我还没有创建 SkillsCV table,现在我只有 CV 和技能(每个技能都有一个 CV_ID),但是当我需要在前端,我需要 return 来自 API 的 DISTINCT 技能(因为有 800 个 C# 例如记录不同的 CV)。我认为 SkillsCVs table 可以解决这个问题,但我现在还不确定 :D

如果我理解正确,你可以只用注释来完成。

 public class Skill
 {
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
 }
 public class Cv
 {
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
 }
 public class SkillCv
 {
    [ForeignKey("Skill")]
    public int SkillId { get; set; }
    [ForeignKey("Cv")]
    public int CvId { get; set; }

    public virtual Skill Skill{ get; set; }

    public virtual  Cv Cv { get; set; }
 }

public class TestContext : DbContext
{
    public DbSet<Skill> Skills { get; set; }
    public DbSet<Cv> Cvs { get; set; }
    public DbSet<SkillCv> SkillCvs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        //The entity does not have its own key, only the relationship of the two
        modelBuilder.Entity<SkillCv>().HasNoKey();
    }

}

因此,对于具有 cv

的每个技能,您将在 table 中占一行
var allSkillFromCv = await _context.SkillCvs.Where(s => s.CvId == 1).ToListAsync()

如果要使用导航属性

var allSkillFromCv = await _context.SkillCvs.Where(s => s.CvId == 1).Include(s => s.Skill).ToListAsync();

你拥有的是many-to-many关系。你可以这样建模:

public class Skill
 {
    public int Id { get; set; }

    public string Name { get; set; }
 }

 public class CV
 {
    public int Id { get; set; }

    public string Name { get; set; }
 }

 public class SkillCV
 {
    public int SkillID { get; set; }

    public Skill Skill { get; set; }

    public int CVID { get; set; }

    public CV CV { get; set; }
 }

然后要使用 Fluent API 进行设置,您可以这样做:

modelBuilder.Entity<SkillCV>()
    .HasKey(t => new { t.SkillID, t.CVID});

modelBuilder.Entity<SkillCV>()
    .HasOne(pt => pt.Skill)
    .WithMany()
    .HasForeignKey(pt => pt.SkillID);

modelBuilder.Entity<SkillCV>()
    .HasOne(pt => pt.CV)
    .WithMany()
    .HasForeignKey(pt => pt.CVID);

这样你以后的连接会很简单,SkillCV table 将有一个由 SkillIDCVID 组成的复合键(确保参照完整性) .

您需要三个 table:简历 Table、技能 Table 和技能简历 Table。你有一个 简历 Table 和技能 Table 之间的多对多关系。您必须使用 Fluent API 定义多对多关系。你需要在简历 Table 和技能 Table

中导航 属性
public class CV
{
    .... 

    public IList<SkillCV> SkillsCVs { get; set; }
}
 public class Skill
 {
        .... 

        public IList<SkillCV> SkillsCVs { get; set; }
 }

在数据库上下文中

  public DbSet<SkillCV> SkillsCVs { get; set; }

您还需要使用 Fluent 定义关系 API

modelBuilder.Entity<SkillCV>()
    .HasOne<Skill>(sc => sc.Skill)
    .WithMany(s => s.SkillsCVs)
    .HasForeignKey(sc => sc.SkillID);


modelBuilder.Entity<SkillCV>()
    .HasOne<CV>(sc => sc.CV)
    .WithMany(s => s.SkillsCVs)
    .HasForeignKey(sc => sc.CvID);