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:
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.
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.
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.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments