这是什么类型的关系以及如何在 .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 将有一个由 SkillID
和 CVID
组成的复合键(确保参照完整性) .
您需要三个 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);
我遇到的问题很简单,但我的脑子不灵了。对不起,如果我的问题很愚蠢,但我不太擅长数据库(我也不擅长 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 将有一个由 SkillID
和 CVID
组成的复合键(确保参照完整性) .
您需要三个 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);