我正在使用 Entity Framework 5 和 MVC 4,以及使用 Code First 迁移的 .NET 4.5。我在 1 到 0 或 1 关系中的两个实体之间有外键。当我尝试为 Jogger 创造记录时,一切都崩溃了。我收到以下错误消息:
- 外键是空引用
- dbo.Jogger 不存在
- 未处理的异常...没有元数据。
当我运行 EF 查看器时,导航关系是完美的。目前没有使用 Fluent API 代码。
用户类
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
// Other properties
public int? JoggerId { get; set; }
public virtual Jogger Jogger { get; set; }
慢跑类
[ForeignKey("UserId")]
public int JoggerId { get; set; }
public virtual UserProfile UserId { get; set; }
当生成 JoggerController 时,它会为 Get 和 Post 方法生成以下代码:
// GET: /Jogger/Create
public ActionResult Create()
{
ViewBag.JoggerId = new SelectList(db.UserProfiles, "UserId", "UserName");
return View();
}
//
// POST: /Jogger/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Jogger jogger)
{
if (ModelState.IsValid)
{
db.Jogger.Add(jogger);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.JoggerId = new SelectList(db.UserProfiles, "UserId", "UserName", jogger.JoggerId);
return View(jogger);
}
根据生成的代码,在 Jogger/Create View 中没有 JoggerId 或 UserId 字段。
通常它在输出显示 JoggerId = 0 和 UserId = null 的代码 (ModelState.IsValid) 部分失败。
我在 asp.net 网站上的 Contoso 大学教程中没有看到这种行为,我也查看了 MSDN Learn EF 站点。我似乎无法解决这个问题。感谢您的建议。
最佳答案
经过反复试验,我找到了一种可以为外键赋值的方法。
首先,我的关系设置不正确:UserProfile 类 不需要 public int? GolferId 表示导航属性。 final类如下所示:
用户资料
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
// Navigation properties
public virtual Jogger Jogger { get; set; }
慢跑类
[Key]
[ForeignKey("UserId")]
public int JoggerId { get; set; }
public string Pronation {get; set;}
public virtual UserProfile UserId { get; set; }
这无需任何 Fluent API 代码即可设置正确的关系。
分配 ForeignKey 值有点棘手,我相信有比这更好的方法。
- 我没有使用定义 (id = 0) 的其他脚手架方法,而是使用了 FormCollection。您还可以使用 [Bind(Include = "field1, field2, field3")] 来确保发布正确的字段。
- 利用 User.Identity.Name 获得登录用户的 UserId 有很长的路要走
FormCollection 允许我引用和保存其他字段,例如旋前
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Create(FormCollection values) { var jogger = new Jogger(); TryUpdateModel(jogger); var context = new TestContext(); var userqq = User.Identity.Name; var user = context.UserProfiles.SingleOrDefault(u => u.UserName == userqq); if (ModelState.IsValid) { jogger.JoggerId = user.UserId; jogger.Pronation = values["Pronation"]; db.Joggers.Add(jogger); db.SaveChanges(); return View(); } ViewBag.JoggerId = new SelectList(db.UserProfiles, "UserId", "UserName", jogger.JoggerId); return View(jogger); }
这一点都不漂亮,但确实有效。感谢@Moeri 为我指明了正确的方向。
关于c# - 将 UserId 分配给外键 = null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18012605/