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.

Original source