C# 如何创建API端点以获取包括学生在内的部门?
我已经用学生和系实体实现了一个.net核心web api。这些实体之间实现了一对一的关系,其中departmentid是学生表的foreignkey。如何在DepartmentController中实现api端点以获取包含学生的所有部门 DepartmentController.csC# 如何创建API端点以获取包括学生在内的部门?,c#,entity-framework,linq,asp.net-core-webapi,endpoint,C#,Entity Framework,Linq,Asp.net Core Webapi,Endpoint,我已经用学生和系实体实现了一个.net核心web api。这些实体之间实现了一对一的关系,其中departmentid是学生表的foreignkey。如何在DepartmentController中实现api端点以获取包含学生的所有部门 DepartmentController.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Micr
using System;
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);
}
}
}
using System;
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; }
}
}
using System;
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; }
}
}
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; }
}
}
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(List<Student> student)
{
try
{
for (var i = 0; i < student.ToArray().Length; i++)
{
_context.Students.Add(student[i]);
}
_context.SaveChanges();
return CreatedAtAction("GetStudents", student);
}
catch
{
return BadRequest();
}
/*_context.Students.Add(student);
await _context.SaveChangesAsync();
return CreatedAtAction("GetStudent", new { id = student.SId }, student);*/
}
/*[HttpPost]
[Route("StudentList")]
public async Task<ActionResult<Student>> PostStudentList([FromBody] List<Student> student)
{
try
{
for (var i = 0; i < student.ToArray().Length; i++)
{
_context.Students.Add(student[i]);
}
_context.SaveChanges();
return CreatedAtAction("GetStudents", student);
}
catch
{
return BadRequest();
}
}*/
// 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);
}
}
}
Student.cs
using System;
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);
}
}
}
using System;
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; }
}
}
using System;
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; }
}
}
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; }
}
}
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(List<Student> student)
{
try
{
for (var i = 0; i < student.ToArray().Length; i++)
{
_context.Students.Add(student[i]);
}
_context.SaveChanges();
return CreatedAtAction("GetStudents", student);
}
catch
{
return BadRequest();
}
/*_context.Students.Add(student);
await _context.SaveChangesAsync();
return CreatedAtAction("GetStudent", new { id = student.SId }, student);*/
}
/*[HttpPost]
[Route("StudentList")]
public async Task<ActionResult<Student>> PostStudentList([FromBody] List<Student> student)
{
try
{
for (var i = 0; i < student.ToArray().Length; i++)
{
_context.Students.Add(student[i]);
}
_context.SaveChanges();
return CreatedAtAction("GetStudents", student);
}
catch
{
return BadRequest();
}
}*/
// 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;
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);
}
}
}
using System;
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; }
}
}
using System;
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; }
}
}
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; }
}
}
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(List<Student> student)
{
try
{
for (var i = 0; i < student.ToArray().Length; i++)
{
_context.Students.Add(student[i]);
}
_context.SaveChanges();
return CreatedAtAction("GetStudents", student);
}
catch
{
return BadRequest();
}
/*_context.Students.Add(student);
await _context.SaveChangesAsync();
return CreatedAtAction("GetStudent", new { id = student.SId }, student);*/
}
/*[HttpPost]
[Route("StudentList")]
public async Task<ActionResult<Student>> PostStudentList([FromBody] List<Student> student)
{
try
{
for (var i = 0; i < student.ToArray().Length; i++)
{
_context.Students.Add(student[i]);
}
_context.SaveChanges();
return CreatedAtAction("GetStudents", student);
}
catch
{
return BadRequest();
}
}*/
// 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);
}
}
}
使用System.Collections.Generic;
使用System.Linq;
使用System.Threading.Tasks;
使用Microsoft.EntityFrameworkCore;
名称空间学生。模型
{
公共类StudentContext:DbContext
{
public StudentContext(DbContextOptions):基本(选项)
{
}
公共数据库集学生{get;set;}
公共数据库集部门{get;set;}
}
}
StudentController.cs
请参考GetStudents()
使用System.Collections.Generic;
使用System.Linq;
使用System.Threading.Tasks;
使用Microsoft.AspNetCore.Http;
使用Microsoft.AspNetCore.Mvc;
使用Microsoft.EntityFrameworkCore;
使用学生模型;
名称空间学生。控制器
{
[路由(“api/[控制器]”)]
[ApiController]
公共班级学生控制员:控制员数据库
{
私有只读StudentContext\u context;
公共学生控制器(学生上下文)
{
_上下文=上下文;
}
//获取:api/学生
[HttpGet]
公共异步任务GetStudents()
{
return wait_context.Students.Include(d=>d.Department.toListSync();
}
//获取:api/Students/5
[HttpGet(“{id}”)]
公共异步任务GetStudent(int id)
{
var student=wait _context.Students.Include(d=>d.Department).FirstOrDefaultAsync(i=>i.SId==id);
如果(学生==null)
{
返回NotFound();
}
留学生;
}
//PUT:api/Students/5
//若要防止套印攻击,请启用要绑定到的特定属性,例如
//更多详细信息请参见https://aka.ms/RazorPagesCRUD.
[HttpPut(“{id}”)]
公共异步任务PutStudent(int-id,Student-Student)
{
if(id!=student.SId)
{
返回请求();
}
_上下文。系。更新(学生。系);
wait_context.SaveChangesAsync();
_context.Entry(student.State=EntityState.Modified;
尝试
{
wait_context.SaveChangesAsync();
}
catch(DbUpdateConcurrencyException)
{
如果(!StudentExists(id))
{
返回NotFound();
}
其他的
{
投掷;
}
}
返回Ok();
}
//职位:api/学生
//若要防止套印攻击,请启用要绑定到的特定属性,例如
//更多详细信息请参见https://aka.ms/RazorPagesCRUD.
[HttpPost]
公共异步任务PostStudent(学生列表)
{
尝试
{
for(var i=0;ie.SId==id);
}
}
}
您要查找的可能是:在学生上下文中使用include方法包括该系,如下所示:
context.Students.Include(student => student.Department);
可能是您必须更新映射,以便EF能够理解它。在这种情况下,如果需要,在映射中需要包含一个HasOne(student=>student.Department)。或者在部门映射中,使用HasMany(Department=>Department.Students)(但您的部门没有学生集合,因此除非您更改模型,否则后者将不是选项)修改
部门
类以包含学生
导航属性
public virtual Student Student { get; set; }
然后在GetDepartments()
方法中,包含Student属性
var query = _context.Departments.Include(d => d.Student);
它返回一个IQueryable,因此您可以添加另一个筛选
var filteredQuery = query.Where(d => d.Student.Name.Contains("jane"));
在你还它之前
return query.ToList();
或
我试过这个。但它在学生和系之间造成了循环依赖 如上所述,您可以在
D中添加Student
导航属性