我有一个Project
实体,定义为:
public class Project
{
[Key]
public Guid ProjectId { get; set; }
//...
[Required, ForeignKey("User")]
public Guid UserId { get; set; }
public virtual User User { get; set; }
}
在我的控制器中,我有:
// insert
public IHttpActionResult Post([FromBody] ProjectDTO projectDTO)
{
return Save(projectDTO);
}
// update
public IHttpActionResult Post(Guid id, [FromBody] ProjectDTO projectDTO)
{
return Save(projectDTO);
}
private IHttpActionResult Save(ProjectDTO projectDTO)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
var isNew = projectDTO.ProjectId == Guid.Empty;
Project project;
if (isNew)
{
project = new Project();
var user = UserManager.FindByName(User.Identity.Name);
projectDTO.UserId = new Guid(user.UserId.ToString());
DbContext.Entry(project).State = EntityState.Added;
}
else
{
project= DbContext.Projects.Find(projectDTO.ProjectId);
if (project == null) return NotFound();
DbContext.Entry(project).State = EntityState.Modified;
}
// set fields from DTO to User...
DbContext.SaveChanges();
// issue:
return Ok(project);
}
问题在于,当控制器返回新插入的项目时,虚拟字段User
将为null,因为尚未使用用户数据加载/填充该字段。
在线路上,// issue:
我尝试了以下两条线路:
if (isNew)
{
// try one of these two lines:
DbContext.Entry(project).Reload();
project = DbContext.Projects.Find(project.ProjectId);
}
但是两者都没有作用:我认为使用Find
并不会真正返回数据库,因为该实体已经存在于上下文中,因此它只是返回该实体。但是我本以为重新加载会迫使项目与FK关系完全重新加载,但事实并非如此。
我可以做这样的事情:
if (isNew)
{
project.User = DbContext.Users.Find(project.UserId);
}
但这看上去并不像我想要的那么干净:我必须为要返回的每个FK进行此操作。
处理此问题的最佳方法是什么?
您可以先将其拆离,这将强制重新加载:
DbContext.Entry(project).State = EntityState.Detached;
project = DbContext.Projects.Find(project.ProjectId);
如果这不起作用,您可以使用ObjectContext
代替它来分离它,但是这可能会在EF的未来版本(DbContext
不使用ObjectContext
)上停止工作:
((IObjectContextAdapter)DbContext).ObjectContext.Detach(project);
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句