将UserId分配给外键= null

Spr*_*kie 6 c# asp.net-mvc entity-framework asp.net-mvc-4

我正在使用Entity Framework 5和MVC 4,使用.NET 4.5使用Code First迁移.我在两个实体之间有1到0或1关系的外键.当我尝试为Jogger创建记录时,一切都会爆炸.我收到的错误消息是:

  • 外键是空引用
  • dbo.Jogger不存在
  • 未处理的异常......没有元数据.

当我运行EF Viewer时,导航关系是完美的.目前没有使用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; }
Run Code Online (Sandbox Code Playgroud)

慢跑者班

    [ForeignKey("UserId")]
    public int JoggerId { get; set; }

    public virtual UserProfile UserId { get; set; }
Run Code Online (Sandbox Code Playgroud)

生成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);
    }
Run Code Online (Sandbox Code Playgroud)

在Jogger/Create视图中,根据生成的代码,没有JoggerId或UserId的字段.

通常,它在代码的(ModelState.IsValid)部分失败,其中Output显示JoggerId = 0和UserId = null.

我没有在asp.net网站上的Contoso大学教程中看到这种行为,我也查看了MSDN学习EF网站.我似乎无法解决这个问题.您的建议表示赞赏.

Spr*_*kie 3

经过多次尝试和错误,我找到了一种为外键分配值的方法。

首先,我的关系设置不正确:UserProfile 类不需要 public int?GolferId 代表导航属性。最终课程如下:

用户资料

  [Key]
  [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
  public int UserId { get; set; }
  public string UserName { get; set; }

  // Navigation properties
  public virtual Jogger Jogger { get; set; }
Run Code Online (Sandbox Code Playgroud)

慢跑班

[Key] 
[ForeignKey("UserId")]
public int JoggerId { get; set; }

public string Pronation {get; set;}

public virtual UserProfile UserId { get; set; }
Run Code Online (Sandbox Code Playgroud)

这无需任何 Fluent API 代码即可设置正确的关系。

分配ForeignKey值有点棘手,我确信有比这更好的方法。

  1. 我使用了 FormCollection,而不是其他定义 (id = 0) 的脚手架方法。您还可以使用 [Bind(Ininclude = "field1, field2, field3")] 确保发布正确的字段。
  2. 利用 User.Identity.Name 获取登录用户的 UserId 有很长的路要走
  3. FormCollection 允许我引用并保存其他字段,例如 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);
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

这一点都不漂亮,但确实有效。感谢@Moeri 为我指明了正确的方向。