如何将DTO数据映射到导航属性并为Review实体设置用户外键
EF 为Review关联User外键实现方案
步骤1:完善Review模型,添加显式外键
建议优先在Review类里添加显式外键字段,符合EF约定配置规则,后续操作更高效:
public class Review { public int id { get; set; } public virtual Movie Movie { get; set; } public virtual User User { get; set; } // 新增显式外键,EF会自动关联User表的id主键 public int UserId { get; set; } public int goreRating { get; set; } public int shockRating { get; set; } public int jumpRating { get; set; } public int plotRating { get; set; } public int supernaturalRating { get; set; } public string description { get; set; } public bool isSpoiler { get; set; } }
添加后执行EF迁移更新数据库结构即可。
步骤2:确认用户ID的获取来源
你可以选择两种方式拿到需要关联的用户ID:
- 扩展ReviewDTO,新增
UserId属性,由请求发起方携带当前登录用户ID传入控制器 - 从后端鉴权上下文直接读取当前登录用户ID(比如JWT解析的Claims、Identity鉴权的User对象),不需要前端传值
步骤3:控制器内给Review赋值外键
调整你的控制器代码,创建Review对象时直接给外键赋值即可,同时补全空值判断和保存操作:
// 首先校验查询的Movie是否存在,避免空引用异常 var movie = db.Movies.FirstOrDefault(i => i.id == reviewDTO.movieId); if (movie == null) { // 可返回不存在提示,比如NotFound() return NotFound("对应电影不存在"); } Review review = new Review() { goreRating = reviewDTO.goreRating, shockRating = reviewDTO.shockRating, jumpRating = reviewDTO.jumpRating, plotRating = reviewDTO.plotRating, supernaturalRating = reviewDTO.supernaturalRating, description = reviewDTO.description, isSpoiler = reviewDTO.isSpoiler, // 赋值用户外键,可替换为从鉴权上下文读取的当前用户ID UserId = reviewDTO.UserId }; try { movie.Reviews.Add(review); // 提交更改到数据库 db.SaveChanges(); } catch (Exception ex) { // 自行补充异常处理逻辑 }
可选方案:直接赋值User导航属性
如果你不想在Review里加显式外键字段,也可以先查询对应用户对象,再赋值给Review的User导航属性:
// 先查询对应用户 var user = db.Users.FirstOrDefault(u => u.id == 待关联的用户ID); if (user == null) { return NotFound("对应用户不存在"); } Review review = new Review() { // 其他属性赋值不变 User = user };
该方案需要多查一次User表,性能不如直接赋值外键,更推荐使用显式外键的方案。
内容的提问来源于stack exchange,提问作者Mr_Happy
相关产品推荐
相关产品推荐

