晚上好。
我正在构建一个用于项目管理的小型Web API。
每个项目都分为许多任务。
最终我尝试从Task对象(slave)访问Project对象(master),但是GET请求(在Task上)没有通过postman响应或者通过chrome得到不完整的响应,就像这样:
GET / api / task / 1:
{
"id": 1,
"name": "Task A",
"description": "Primary task",
"priority": 0,
"state": 0,
"projectId": 1,
"project": {
"id": 1,
"name": "Project 1",
"description": "First project",
"deadline": "0001-01-01T00:00:00",
"clientId": 0,
"tasks": [
我将介绍模型,上下文和控制器类,我希望得到如何正确指示EF以包含与任务中的外键字段对应的Project对象的帮助。
以下是Project模型的类:
//Project.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace ProjectManagementAPI.Models
{
public class Project
{
public Project()
{
Tasks = new List<Task>();
}
public int Id { get; set; }
public String Name { get; set; }
public String Description { get; set; }
public DateTime Deadline { get; set; }
public int ClientId { get; set; }
public ICollection<Task> Tasks { get; set; }
}
}
对于任务:
//Task.cs
namespace ProjectManagementAPI.Models
{
public enum STATE { Pending, Started, Blocked, Finished }
public class Task
{
public Task()
{
}
public int Id { get; set; }
public String Name { get; set; }
public String Description { get; set; }
public int Priority { get; set; }
public STATE State { get; set; }
[ForeignKey("ProjectId")]
public int ProjectId { get; set; }
public Project Project { get; set; }
}
}
Context类通过Fluent API详细说明了该关系:
//ProjectManagementDBEntities.cs
namespace ProjectManagementAPI.Models
{
public class ProjectManagementDBEntities : DbContext
{
public ProjectManagementDBEntities(DbContextOptions<ProjectManagementDBEntities> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Task>()
.HasOne(p => p.Project)
.WithMany(b => b.Tasks)
.OnDelete(DeleteBehavior.Cascade);
}
public DbSet<Project> Projects { get; set; }
public DbSet<Task> Tasks { get; set; }
}
}
项目控制器类(省略更新和删除控件):
//ProjectController.cs
namespace ProjectManagementAPI.Controllers
{
[Route("api/[controller]")]
public class ProjectController : Controller
{
private readonly ProjectManagementDBEntities _context;
public ProjectController(ProjectManagementDBEntities context)
{
_context = context;
}
[HttpGet]
public IEnumerable<Project> GetAll()
{
return _context.Projects.ToList();
}
[HttpGet("{id}", Name = "GetProject")]
public IActionResult GetById(long id)
{
var project = _context.Projects.FirstOrDefault(t => t.Id == id);
if (project == null)
{
return NotFound();
}
return new ObjectResult(project);
}
[HttpPost]
public IActionResult Create([FromBody] Project project)
{
if (project == null)
{
return BadRequest();
}
project.Tasks = new List<Task>();
_context.Projects.Add(project);
_context.SaveChanges();
return CreatedAtRoute("GetProject", new { id = project.Id }, project);
}
}
在Task控制器中,我使用LINQ的Include()方法来请求对象的预先加载。我怀疑它是错误所在的地方。
//TaskController.cs
namespace ProjectManagementAPI.Controllers
{
[Route("api/[controller]")]
public class TaskController : Controller
{
private readonly ProjectManagementDBEntities _context;
public TaskController(ProjectManagementDBEntities context)
{
_context = context;
}
[HttpGet]
public IEnumerable<Task> GetAll()
{
return _context.Tasks.Include(t => t.Project).ToList();
}
[HttpGet("{id}", Name = "GetTask")]
public IActionResult GetById(long id)
{
var task = _context.Tasks.Include(t => t.Project).FirstOrDefault(t => t.Id == id);
if (task == null)
{
return NotFound();
}
return new ObjectResult(task);
}
[HttpPost]
public IActionResult Create([FromBody] Task Task)
{
if (Task == null)
{
return BadRequest();
}
_context.Tasks.Add(Task);
_context.SaveChanges();
return CreatedAtRoute("GetTask", new { id = Task.Id }, Task);
}
}
谢谢。