我应该如何实现在数据库中插入多个学生?
What should I implement to inset multiple Students in database?
在此,我实现了一个 .Net Core web API,其中我有两个模型 类 Student 和 Department。
我已经实现了这两个实体之间的一对一关系。有两个控制器 StudentController 和 DepartmentController。 Student 模型具有 Department 实体的引用,并将 DepartmentId 作为外键。每个学生都被分配到一个系。在数据库中执行多个 Students 条目需要什么实现,以及如何在 Postman 中检查相同的实现?
如何使用 JSON 格式 不使用 ViewModel 创建端点以添加多个学生?
Student.cs
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace Students.Models
{
public class Student
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int SId { get; set; }
[Required]
[Column(TypeName ="varchar(50)")]
public string Name { get; set; }
public int DepartmentId { get; set; }
public Department Department { get; set; }
}
}
Department.cs
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace Students.Models
{
public class Department
{
[Key]
public int Id { get; set; }
[Required]
[Column(TypeName = "varchar(20)")]
public string Dep { get; set; }
}
}
DepartmentController.cs
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Students.Models;
namespace Students.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class DepartmentController : ControllerBase
{
private readonly StudentContext _context;
public DepartmentController(StudentContext context)
{
_context = context;
}
// GET: api/Department
[HttpGet]
public async Task<ActionResult<IEnumerable<Department>>> GetDepartments()
{
return await _context.Departments.ToListAsync();
}
// GET: api/Department/5
[HttpGet("{id}")]
public async Task<ActionResult<Department>> GetDepartment(int id)
{
var department = await _context.Departments.FindAsync(id);
if (department == null)
{
return NotFound();
}
return department;
}
// PUT: api/Department/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
[HttpPut("{id}")]
public async Task<IActionResult> PutDepartment(int id, Department department)
{
if (id != department.Id)
{
return BadRequest();
}
_context.Entry(department).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!DepartmentExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return Ok();
}
// POST: api/Department
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
[HttpPost]
public async Task<ActionResult<Department>> PostDepartment(Department department)
{
_context.Departments.Add(department);
await _context.SaveChangesAsync();
return CreatedAtAction("GetDepartment", new { id = department.Id }, department);
}
// DELETE: api/Department/5
[HttpDelete("{id}")]
public async Task<ActionResult<Department>> DeleteDepartment(int id)
{
var department = await _context.Departments.FindAsync(id);
if (department == null)
{
return NotFound();
}
_context.Departments.Remove(department);
await _context.SaveChangesAsync();
return department;
}
private bool DepartmentExists(int id)
{
return _context.Departments.Any(e => e.Id == id);
}
}
}
StudentsController.cs
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Students.Models;
namespace Students.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class StudentsController : ControllerBase
{
private readonly StudentContext _context;
public StudentsController(StudentContext context)
{
_context = context;
}
// GET: api/Students
[HttpGet]
public async Task<ActionResult<IEnumerable<Student>>> GetStudents()
{
return await _context.Students.Include(d => d.Department).ToListAsync();
}
// GET: api/Students/5
[HttpGet("{id}")]
public async Task<ActionResult<Student>> GetStudent(int id)
{
var student = await _context.Students.Include(d => d.Department).FirstOrDefaultAsync(i => i.SId == id);
if (student == null)
{
return NotFound();
}
return student;
}
// PUT: api/Students/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
[HttpPut("{id}")]
public async Task<IActionResult> PutStudent(int id, Student student)
{
if (id != student.SId)
{
return BadRequest();
}
_context.Departments.Update(student.Department);
await _context.SaveChangesAsync();
_context.Entry(student).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!StudentExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return Ok();
}
// POST: api/Students
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
[HttpPost]
public async Task<ActionResult<Student>> PostStudent(Student student)
{
//_context.Departments.Add(student.Department);
//await _context.SaveChangesAsync();
_context.Students.Add(student);
await _context.SaveChangesAsync();
return CreatedAtAction("GetStudent", new { id = student.SId }, student);
}
// DELETE: api/Students/5
[HttpDelete("{id}")]
public async Task<ActionResult<Student>> DeleteStudent(int id)
{
var student = await _context.Students.FindAsync(id);
if (student == null)
{
return NotFound();
}
_context.Students.Remove(student);
await _context.SaveChangesAsync();
return student;
}
private bool StudentExists(int id)
{
return _context.Students.Any(e => e.SId == id);
}
}
}
StudentContext.cs
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace Students.Models
{
public class StudentContext:DbContext
{
public StudentContext(DbContextOptions<StudentContext> options) : base(options)
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Department> Departments { get; set; }
}
}
StudentContextModelSnapshot.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Students.Models;
namespace Students.Migrations
{
[DbContext(typeof(StudentContext))]
partial class StudentContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Students.Models.Department", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Dep")
.IsRequired()
.HasColumnType("varchar(20)");
b.HasKey("Id");
b.ToTable("Departments");
});
modelBuilder.Entity("Students.Models.Student", b =>
{
b.Property<int>("SId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("DepartmentId")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("varchar(50)");
b.HasKey("SId");
b.HasIndex("DepartmentId");
b.ToTable("Students");
});
modelBuilder.Entity("Students.Models.Student", b =>
{
b.HasOne("Students.Models.Department", "Department")
.WithMany()
.HasForeignKey("DepartmentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}
What implementation is required to perform multiple Students entry in database and how to check the same implementation in Postman?
你可以添加PostStudentList
方法如下:
[HttpPost]
[Route("StudentList")]
public async Task<ActionResult<Student>> PostStudentList([FromForm] List<Student> student)
{
_context.Students.AddRange(student);
await _context.SaveChangesAsync();
return CreatedAtAction("GetStudents", student);
}
使用 Postman 发送具有 form-data
contentType 的学生列表
已更新,以JSON格式发送条目
PostStudentList 方法:
public class StudentVM
{
public List<Student> student { get; set; }
}
[HttpPost]
[Route("StudentList")]
public async Task<ActionResult<Student>> PostStudentList(StudentVM model)
{
var students = new List<Student>();
students = model.student;
_context.Students.AddRange(students);
await _context.SaveChangesAsync();
return CreatedAtAction("GetStudents", students);
}
邮递员:
在此,我实现了一个 .Net Core web API,其中我有两个模型 类 Student 和 Department。 我已经实现了这两个实体之间的一对一关系。有两个控制器 StudentController 和 DepartmentController。 Student 模型具有 Department 实体的引用,并将 DepartmentId 作为外键。每个学生都被分配到一个系。在数据库中执行多个 Students 条目需要什么实现,以及如何在 Postman 中检查相同的实现? 如何使用 JSON 格式 不使用 ViewModel 创建端点以添加多个学生?
Student.cs
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace Students.Models
{
public class Student
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int SId { get; set; }
[Required]
[Column(TypeName ="varchar(50)")]
public string Name { get; set; }
public int DepartmentId { get; set; }
public Department Department { get; set; }
}
}
Department.cs
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace Students.Models
{
public class Department
{
[Key]
public int Id { get; set; }
[Required]
[Column(TypeName = "varchar(20)")]
public string Dep { get; set; }
}
}
DepartmentController.cs
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Students.Models;
namespace Students.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class DepartmentController : ControllerBase
{
private readonly StudentContext _context;
public DepartmentController(StudentContext context)
{
_context = context;
}
// GET: api/Department
[HttpGet]
public async Task<ActionResult<IEnumerable<Department>>> GetDepartments()
{
return await _context.Departments.ToListAsync();
}
// GET: api/Department/5
[HttpGet("{id}")]
public async Task<ActionResult<Department>> GetDepartment(int id)
{
var department = await _context.Departments.FindAsync(id);
if (department == null)
{
return NotFound();
}
return department;
}
// PUT: api/Department/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
[HttpPut("{id}")]
public async Task<IActionResult> PutDepartment(int id, Department department)
{
if (id != department.Id)
{
return BadRequest();
}
_context.Entry(department).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!DepartmentExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return Ok();
}
// POST: api/Department
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
[HttpPost]
public async Task<ActionResult<Department>> PostDepartment(Department department)
{
_context.Departments.Add(department);
await _context.SaveChangesAsync();
return CreatedAtAction("GetDepartment", new { id = department.Id }, department);
}
// DELETE: api/Department/5
[HttpDelete("{id}")]
public async Task<ActionResult<Department>> DeleteDepartment(int id)
{
var department = await _context.Departments.FindAsync(id);
if (department == null)
{
return NotFound();
}
_context.Departments.Remove(department);
await _context.SaveChangesAsync();
return department;
}
private bool DepartmentExists(int id)
{
return _context.Departments.Any(e => e.Id == id);
}
}
}
StudentsController.cs
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Students.Models;
namespace Students.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class StudentsController : ControllerBase
{
private readonly StudentContext _context;
public StudentsController(StudentContext context)
{
_context = context;
}
// GET: api/Students
[HttpGet]
public async Task<ActionResult<IEnumerable<Student>>> GetStudents()
{
return await _context.Students.Include(d => d.Department).ToListAsync();
}
// GET: api/Students/5
[HttpGet("{id}")]
public async Task<ActionResult<Student>> GetStudent(int id)
{
var student = await _context.Students.Include(d => d.Department).FirstOrDefaultAsync(i => i.SId == id);
if (student == null)
{
return NotFound();
}
return student;
}
// PUT: api/Students/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
[HttpPut("{id}")]
public async Task<IActionResult> PutStudent(int id, Student student)
{
if (id != student.SId)
{
return BadRequest();
}
_context.Departments.Update(student.Department);
await _context.SaveChangesAsync();
_context.Entry(student).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!StudentExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return Ok();
}
// POST: api/Students
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see https://aka.ms/RazorPagesCRUD.
[HttpPost]
public async Task<ActionResult<Student>> PostStudent(Student student)
{
//_context.Departments.Add(student.Department);
//await _context.SaveChangesAsync();
_context.Students.Add(student);
await _context.SaveChangesAsync();
return CreatedAtAction("GetStudent", new { id = student.SId }, student);
}
// DELETE: api/Students/5
[HttpDelete("{id}")]
public async Task<ActionResult<Student>> DeleteStudent(int id)
{
var student = await _context.Students.FindAsync(id);
if (student == null)
{
return NotFound();
}
_context.Students.Remove(student);
await _context.SaveChangesAsync();
return student;
}
private bool StudentExists(int id)
{
return _context.Students.Any(e => e.SId == id);
}
}
}
StudentContext.cs
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace Students.Models
{
public class StudentContext:DbContext
{
public StudentContext(DbContextOptions<StudentContext> options) : base(options)
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Department> Departments { get; set; }
}
}
StudentContextModelSnapshot.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Students.Models;
namespace Students.Migrations
{
[DbContext(typeof(StudentContext))]
partial class StudentContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Students.Models.Department", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Dep")
.IsRequired()
.HasColumnType("varchar(20)");
b.HasKey("Id");
b.ToTable("Departments");
});
modelBuilder.Entity("Students.Models.Student", b =>
{
b.Property<int>("SId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<int>("DepartmentId")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("varchar(50)");
b.HasKey("SId");
b.HasIndex("DepartmentId");
b.ToTable("Students");
});
modelBuilder.Entity("Students.Models.Student", b =>
{
b.HasOne("Students.Models.Department", "Department")
.WithMany()
.HasForeignKey("DepartmentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}
What implementation is required to perform multiple Students entry in database and how to check the same implementation in Postman?
你可以添加PostStudentList
方法如下:
[HttpPost]
[Route("StudentList")]
public async Task<ActionResult<Student>> PostStudentList([FromForm] List<Student> student)
{
_context.Students.AddRange(student);
await _context.SaveChangesAsync();
return CreatedAtAction("GetStudents", student);
}
使用 Postman 发送具有 form-data
contentType 的学生列表
已更新,以JSON格式发送条目
PostStudentList 方法:
public class StudentVM
{
public List<Student> student { get; set; }
}
[HttpPost]
[Route("StudentList")]
public async Task<ActionResult<Student>> PostStudentList(StudentVM model)
{
var students = new List<Student>();
students = model.student;
_context.Students.AddRange(students);
await _context.SaveChangesAsync();
return CreatedAtAction("GetStudents", students);
}
邮递员: