У меня есть отношение между Student
к StudentSkill
, а затем StudentSkill
к Skills
. Я пытаюсь создать API, который будет возвращать учащимся список их навыков, соответствующих идентификатору.
В моей базе данных, когда я запускаю этот запрос, он работает нормально ...
select s.Name, sk.Name, sk.SkillId
from Students s
join StudentSkills ss on ss.StudentId = s.StudentId
join Skills sk on sk.SkillId = ss.SkillId
Что возвращает запрос. Jpg
Вот мои уроки:
[JsonObject(IsReference = true)]
public class Skill
{
[Key] // Denotes that this field will be used as the Key.
// Tells the database to auto generate the next key with every new skill.
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int SkillId { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
[MaxLength(50)]
public string Level { get; set; }
public virtual ICollection<StudentSkill> Students { get; set; }
}
public class StudentSkill
{
public int StudentId { get; set; }
public virtual Student Student { get; set; }
public int SkillId { get; set; }
public virtual Skill Skill { get; set; }
}
public enum Gender { Male,Female}
[JsonObject(IsReference = true)]
public class Student
{
[Key] // Denotes that this field will be used as the Key.
// Tells the database to auto generate the next key with every new student.
public int StudentId { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
[Required]
public int Age { get; set; }
public Gender Gender { get; set; }
public virtual ICollection<StudentSkill> Skills { get; set; }
}
Мое отображение выглядит так:
public class StudentSkillProfile : Profile
{
public StudentSkillProfile()
{
CreateMap<Student, StudentDto>()
.ForMember(s => s.Id, opts => opts.MapFrom(src => src.StudentId));
CreateMap<Skill, SkillsDto>()
.ForMember(s => s.Id, opts => opts.MapFrom(source => source.SkillId));
CreateMap<StudentSkill, SkillsDto>()
.ForMember(d => d.Id, opt => opt.MapFrom(s => s.SkillId));
CreateMap<SkillsDto, StudentSkill>()
.ForMember(d => d.SkillId, opt => opt.MapFrom(s => s.Id));
}
}
и, наконец, мой метод API для возвращения студента:
public Student GetStudent(int studentID, bool includeSkills)
{
if (includeSkills)
{
return _context.Students
.Include(s => s.Skills)
.Where(s => s.StudentId == studentID)
.FirstOrDefault();
}
return _context.Students
.Where(s => s.StudentId == studentID)
.FirstOrDefault();
}
Метод context и modelBuilder:
modelBuilder.Entity<StudentSkill>().HasData(
new StudentSkill() { SkillId = 1, StudentId = 1},
new StudentSkill() { SkillId = 2, StudentId = 1},
new StudentSkill() { SkillId = 3, StudentId = 1},
new StudentSkill() { SkillId = 1, StudentId = 2},
new StudentSkill() { SkillId = 3, StudentId = 2}
);
modelBuilder.Entity<Student>().HasData(
new Student(){Name = "Joe", StudentId = 1, Age = 10, Gender = Gender.Male},
new Student(){Name = "Jen", StudentId = 2, Age = 10, Gender = Gender.Female}
);
modelBuilder.Entity<StudentSkill>()
.HasKey(ss => new { ss.StudentId, ss.SkillId });
modelBuilder.Entity<StudentSkill>()
.HasOne(ss => ss.Skill)
.WithMany(sk => sk.Students)
.HasForeignKey(ss => ss.SkillId);
modelBuilder.Entity<Student
.HasOne(st => st.Student)
.WithMany(sk => sk.Skills)
.HasForeignKey(st => st.StudentId);
modelBuilder.Entity<Skill>().HasData(
new Skill(){ SkillId = 1, Name = "Forward Roll", Level = "Beginner", },
new Skill(){ SkillId = 2, Name = "Backward Roll", Level = "Beginner" },
new Skill(){ SkillId = 3, Name = "CartWheel", Level = "Beginner" }
Это то, что я получаю, когда запускаю его через Почтальон:
Я ожидаю имя и уровень (от Навыков с соответствующим ID) вместо этих нулей
Я все еще довольно новичок в программировании и C#, поэтому во многом это просто я пробую кучу вещей и читаю множество документов. Любая помощь будет оценена. Github для этого проекта Здесь, в ветке NoClue хаха