Assigning UserId to Foreign Key = null
asp.net-mvc, asp.net-mvc-4, c#, entity-framework
Solution
After much trial and error I found a way that works to assign the Foreign Key a value.
Firstly, my relationships were setup incorrectly: UserProfile Class did not need the public int? GolferId to represent a navigation property. Final classes looked as follows:
UserProfile
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
// Navigation properties
public virtual Jogger Jogger { get; set; }
Jogger Class
[Key]
[ForeignKey("UserId")]
public int JoggerId { get; set; }
public string Pronation {get; set;}
public virtual UserProfile UserId { get; set; }
This setup the correct relationship without needing any Fluent API code.
To assign the ForeignKey value was a little trickier and I'm sure there are MUCH better ways of doing it than this.
- Instead of the other scaffolding method of defining (id = 0), I used a FormCollection. You can also use the [Bind(Include = "field1, field2, field3")] to ensure that the correct fields are being posted.
- There's a long way of getting to the logged-in User's UserId which takes advantage of User.Identity.Name
The FormCollection allows me to reference and save the other fields e.g. Pronation
[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);
}
This wasn't pretty at all but it does work. Thanks to @Moeri for pointing me in the right direction.
Problem
I'm using Entity Framework 5 and MVC 4, with .NET 4.5 using Code First migrations. I have foreign keys between two entities in a 1 to zero-or-1 relationship. When I try to create the record for Jogger everything blows up. I get error messages that are either: - Foreign Key is a null reference - dbo.Jogger does not exist - Unhandled exception ... no metadata. When I run the EF Viewer the navigation relationships are perfect. No Fluent API code is used at the moment. User Class ``` [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; } ``` Jogger Class ``` [ForeignKey("UserId")] public int JoggerId { get; set; } public virtual UserProfile UserId { get; set; } ``` When the JoggerController is generated it produces this code for the Get and Post Methods: ``` // 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); } ``` In the Jogger/Create view there are no fields for JoggerId or UserId according to the generated code. Typically it fails on the (ModelState.IsValid) portion of code where the Output shows JoggerId = 0 and UserId = null. I have not seen this behaviour on the Contoso University tutorial on asp.net's website and I have looked at the MSDN Learn EF site as well. I can't seem to solve this problem. Your advice is appreciated.