如何绑定外键? 如何在控制器类中使用外键创建Model对象?
我有以下表格关系:
ProfileMeta 1 ----- 0...1 ProfileDetail
点击“ Profile/Create
页面上的提交后,我收到了运行时错误
Cannot insert the value NULL into column 'ID', table 'ContosoUniversity1.dbo.ProfileMeta'; column does not allow nulls. INSERT fails.
我在Models / ProfileDetail.cs中正确引用了ProfileMeta作为ForeignKey:
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Web; namespace ContosoUniversity.Models { //ProfileMeta is Principal Class //ProfileDetail is Dependent Class public class ProfileDetail { //classNameID or ID is interpreted by EF as PK. public int ID { get; set; } //ForeignKey("") [Key, ForeignKey("ProfileMeta")] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.None)] public int ProfileMetaID {get; set;} public string UserName { get; set; } public string Age { get; set; } public string Location { get; set; } public string Gender { get; set; } //Optional Details public string HighSchool { get; set; } public string UndergraduateSchool { get; set; } public string GraduateSchool { get; set; } public virtual ProfileMeta ProfileMeta { get; set; } } }
型号/ ProfileMeta.cs:
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Web; namespace ContosoUniversity.Models { //ProfileMeta is Principal //ProfileDetail is Dependent public class ProfileMeta { public int ID { get; set; } public string Username { get; set; } public string password { get; set; } public virtual ProfileDetail ProfileDetail {get; set;} public virtual ICollection MessageDetails { get; set; } public virtual ICollection ConversationMetas { get; set; } } }
对于function注册/注册页面,我创建了一个模型:“Register”,它引用了ProfileMeta和ProfileDetail。
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace ContosoUniversity.Models { public class Register { public ProfileMeta ProfileMeta_ { get; set; } public ProfileDetail ProfileDetail_ { get; set; } } }
查看/资料/ Create.cshtml:
@model ContosoUniversity.Models.Register @{ ViewBag.Title = "Create"; } Create
@using (Html.BeginForm()) { @Html.AntiForgeryToken() Profile
@Html.ValidationSummary(true, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.ProfileMeta_.Username, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.ProfileMeta_.Username, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ProfileMeta_.Username, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.ProfileMeta_.password, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.ProfileMeta_.password, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ProfileMeta_.password, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.ProfileDetail_.Age, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.ProfileDetail_.Age, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ProfileDetail_.Age, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.ProfileDetail_.Location, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.ProfileDetail_.Location, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ProfileDetail_.Location, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.ProfileDetail_.Gender, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.ProfileDetail_.Gender, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ProfileDetail_.Gender, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.ProfileDetail_.HighSchool, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.ProfileDetail_.HighSchool, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ProfileDetail_.HighSchool, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.ProfileDetail_.UndergraduateSchool, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.ProfileDetail_.UndergraduateSchool, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ProfileDetail_.UndergraduateSchool, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.ProfileDetail_.GraduateSchool, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.ProfileDetail_.GraduateSchool, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.ProfileDetail_.GraduateSchool, "", new { @class = "text-danger" }) } @Html.ActionLink("Back to List", "Index") @section Scripts { @Scripts.Render("~/bundles/jqueryval") }
ProfileController.cs:
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Create(Register register) { if (ModelState.IsValid) { //Add 1 ProfileMeta row and 1 linked ProfileDetail row ProfileMeta profileMeta = new ProfileMeta(); profileMeta.Username = register.ProfileMeta_.Username; profileMeta.password = register.ProfileMeta_.password; ProfileDetail profileDetail = new ProfileDetail(); //profileDetail.ID = register.ProfileDetail_.ID; //How to assign FK below? profileDetail.ProfileMetaID = register.ProfileDetail_.ID; profileDetail.UserName = register.ProfileDetail_.UserName; profileDetail.Age = register.ProfileDetail_.Age; profileDetail.Location = register.ProfileDetail_.Location; profileDetail.ProfileMeta = profileMeta; //profileDetail.UserName = register.ProfileDetail_.UserName; //profileDetail.Age = register.ProfileDetail_.Age; //profileDetail.Location = register.ProfileDetail_.Location; profileMeta.ProfileDetail = profileDetail; db.ProfileMetas.Add(profileMeta); db.ProfileDetails.Add(profileDetail); db.SaveChanges(); return RedirectToAction("Index"); } return View(register); }
为什么我不能添加一行ProfileMeta和一行ProfileDetail? 我以为数据库会自动生成主键(或ID)。
是否有必要在控制器中为给定的Model对象显式设置导航属性? 另外,我是否需要在我创建的ProfileDetail对象中显式设置外键:“ProfileMetaID”?
首先,我想建议使用EF代码约定,而不是明确定义EF中的关系(您的声明是正确的,它只是我个人的偏好,我认为它更清洁)。
所以不是这样的:
//ForeignKey("") [Key, ForeignKey("ProfileMeta")] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.None)] public int ProfileMetaID {get; set;} public virtual ProfileMeta ProfileMeta { get; set; }
你可以做:
public int ProfileMetaID { get; set; } public virtual ProfileMeta profileMeta { get; set; }
EF
将在DB中自动为您创建FK
。
至于您的问题,我强烈建议您使用ViewModel并包含您想要使用的所有属性。 但是如果要使用现有模型,可以使用ProfileMeta
作为基本模型,并使用model.profileDetail.Age
绑定ProfileDetail
的值。
这是一个例子:
你的型号(短版)
public class ProfileDetail { [Key, DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int ID { get; set; } public string UserName { get; set; } public string Age { get; set; } public string Location { get; set; } public string Gender { get; set; } public int ProfileMetaID { get; set; } public virtual ProfileMeta profileMeta { get; set; } } public class ProfileMeta { [Key, DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int ID { get; set; } public string Username { get; set; } public string password { get; set; } public virtual ProfileDetail profileDetail {get; set;} }
你的控制器:(不需要显式设置属性的值,因为关系和EF
会处理它。)
[HttpGet] public ActionResult Create() { return View(new ProfileMeta()); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create(Register register) { if (ModelState.IsValid) { db.ProfileMetas.Add(profileMeta); db.ProfileDetails.Add(profileDetail); db.SaveChanges(); } }
在您的视图中(只是一个快照)
@Html.LabelFor(model => model.Username, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.Username, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Username, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.password, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.password, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.password, "", new { @class = "text-danger" }) @Html.LabelFor(model => model.profileDetail.Age, htmlAttributes: new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.profileDetail.Age, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.profileDetail.Age, "", new { @class = "text-danger" })
最后,这是一个说明整个概念的小提琴: https : //dotnetfiddle.net/N0prMA
在小提琴中,您将看到如果您提供年龄,它将提交回来并在页面中显示。
上述就是C#学习教程:如何绑定外键? 如何在控制器类中使用外键创建Model对象?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/954879.html