我正在将集合添加到现有数据集中。我有一个学生,其主题仍为null
。因此,我正在做的就是post
将收藏集放入该学生。
这是我的code
:
[HttpPost("{id}/subjects")]
public async Task<ActionResult<object>> PostStudentSubject(string id, Subject item)
{
// this is to get whole subject model using id
Subject subj = await _context.Subjects.FindAsync(item.Id);
// this is to get student model through the given id in parameter
Student stud = await _context.FirstOrDefaultAsync(p => p.Id == id);
if (stud == null){
return NotFound();
}
// this is to remove the "subj" to avoid an Exception:
// "The property 'Id' is part of the object's key information and cannot be modified"
_context.Subjects.Remove(subj);
await _context.SaveChangesAsync();
// and this is now to add a new object Subject to the
// collection of subjects in the student
stud.Subjects.Add(new Subject { Id = subj.Id });
// some subject properties are omitted...
await _context.SaveChangesAsync();
return Ok(stud);
}
它返回OK
,但是Swagger响应返回这些:
服务器响应
代码->未记录,详细信息->错误:确定
回复
代码-> 200,说明->成功
可见的问题是受试者的ID 将更改为学生的ID 。为什么会这样呢?而我在哪一部分上得到这个?
主题
public class Subject
{
[Key]
public string Id { get; set; }
// some codes omitted ...
[ForeignKey("Id")]
public Student student {get; set;}
}
学生
public class Student
{
[Key]
public string Id { get; set; }
// some codes omitted ...
public IList<Subject> Subjects {get; set;} = new List<Subject>();
}
答案 0 :(得分:1)
问题是外键:
[ForeignKey("Id")]
public Student student {get; set;}
主题表应具有一个StudentId列,以指向适用的学生。照原样,您是在告诉Subject它的PK应该是学生ID。 (就像一对一关系)
如果是代码优先,则在EF中:
public class Subject
{
[Key]
public string Id { get; set; } // ID for the Subject
// some codes omitted ...
public string StudentId { get; set; } // FK to the student.
[ForeignKey("StudentId")]
public Student student {get; set;}
}
但是,学生与科目之间的关系应该是多对多的关系,其中许多学生可以与许多相同的科目相关联。 (一个学生有很多科目,而一个学科有很多学生)
要执行此操作,您需要一个名为StudentSubjects之类的链接表。
StudentSubjects
StudentId [PK] [FK -> Students]
SubjectId [PK] [FK -> Subjects]
EF可以自动管理该表,只要它仅包含组合键而没有其他字段即可。否则,您需要将其定义为实体并手动提供映射。
public class Student
{
[Key]
public int Id { get; set; }
public virtual ICollection<Subject> Subjects { get; set; } = new List<Subject>();
}
public class Subject
{
[Key]
public int Id { get; set; }
public virtual ICollection<Student> Students { get; set; } = new List<Student>();
}
如果使用CodeFirst,则应建立一个StudentSubjects(或SubjectStudents)表来管理关系。否则,您可以映射HasMany.WithMany并定义表格,左右键关系...
即用于学生EntityTypeConfiguration
// EF6 Syntax. EF Core will be a tad different /w IEntityTypeConfiguration<Student> implementation.
public class StudentConfiguration : EntityTypeConfiguration<Student>
{
public StudentConfiguration()
{
HasMany(x => x.Subjects)
.WithMany(x => x.Students)
.Map(x => x.ToTable("StudentSubjects").MapLeftKey("StudentId").MapRightKey("SubjectId"));
}
}
我强烈建议不要对PK使用字符串。它们对于存储和索引而言相当大,您不能使用数据库端身份或诸如NewSequentialId()[GUIDs]之类的默认值