Come progettare classi nidificate in un'API .NET Core per ottenere uno schema particolare?
Sto scherzando con Entity Framework per la prima volta in un'API .NET Core (utilizzando l'ultima versione di .NET Core).
Al momento ho 2 classi:
public class Employee
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public DateTime JoinedCompany { get; set; }
public ICollection<Skill> Skills { get; set; }
}
public class Skill
{
public int Id { get; set; }
public string SkillName { get; set; }
}
Ho anche un corso DBContext
con
public DbSet<Employee> Employees { get; set; }
public DbSet<Skill> Skills { get; set; }
e posso recuperarlo con quanto segue:
public async Task<IReadOnlyList<Employee>> GetEmployeesAsync () {
return await _context.Employees
.Include(p => p.Skills)
.ToListAsync();
}
Ora sto usando le migrazioni di Entity Framework per creare le tabelle. Utilizzando le classi esistenti ottengo le seguenti tabelle due tabelle:
(1) "Dipendenti" con le colonne: Id, FirstName, LastName, Gender, JoinedCompany
(2) "Skills" con le colonne: Id, SkillName, EmployeeId
Ho popolato queste tabelle con alcuni dati e ricevo quanto segue quando ho raggiunto uno degli endpoint dell'API in Postman:
[
{
"firstName": "Jess",
"lastName": "Turner",
"gender": "F",
"joinedCompany": "2018-10-04T00:00:00",
"skills": [
{
"skillName": "T-SQL",
"id": 1
},
{
"skillName": "Angular",
"id": 2
},
{
"skillName": "Vue",
"id": 3
},
{
"skillName": "Redux",
"id": 4
}
],
"id": 1
},
{
"firstName": "Olivia",
"lastName": "Lu",
"gender": "F",
"joinedCompany": "2015-03-31T00:00:00",
"skills": [
{
"skillName": "Hadoop",
"id": 5
},
{
"skillName": "Azure Databricks",
"id": 6
},
{
"skillName": "Spark",
"id": 7
},
{
"skillName": "Python",
"id": 8
},
{
"skillName": "T-SQL",
"id": 9
}
],
"id": 2
},
{
"firstName": "Jonah",
"lastName": "Smythe",
"gender": "M",
"joinedCompany": "2020-08-11T00:00:00",
"skills": [],
"id": 3
}
]
Ora, quello che sto cercando di capire è come posso progettare le classi in modo che quando eseguo crei il database utilizzando il framework di entità in modo da ottenere tre tabelle:
(1) "Dipendenti" con le colonne: Id, FirstName, LastName, Gender, JoinedCompany
(1) "EmployeeSkills" con le colonne: Id, EmployeeId, SkillId
(2) "Skills" con le colonne: Id, SkillName
Il motivo è che non voglio memorizzare la stringa "SkillName" più e più volte ogni volta che appare per il dipendente. Voglio solo usare l'ID. Ciò cambierebbe anche il GetEmployeesAsync
metodo che ho applicato sopra. Grazie.
Risposte
public class Employee
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public DateTime JoinedCompany { get; set; }
public ICollection<EmployeeSkill> Skills { get; set; } = new HashSet<EmployeeSkill>();
}
public class Skill
{
public int Id { get; set; }
public string SkillName { get; set; }
public ICollection<EmployeeSkill> Emploees { get; set; } = new HashSet<EmployeeSkill>();
}
public class EmployeeSkill
{
public int EmployeeId { get; set; }
public Employee Employee { get; set; }
public int SkillId { get; set; }
public Skill Skill { get; set; }
}
public class MyDbContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
public DbSet<Skill> Skills { get; set; }
public DbSet<EmployeeSkill> EmployeesSkills { get; set; }
}