插入数据库前如何设置导航属性?
How Should I Set Navigation Properties Before Inserting Into The Database?
注意:我昨天问了一个 ,但我已经从那个问题转移到了另一个问题。虽然它非常密切相关,但我认为最好在一个单独的问题中表达它。
我有三个模型:Account
、AccountType
和 Person
。我想制作一个表单页面,通过它可以将具有特定 AccountType 和特定人员信息的新帐户 POST 编辑到数据库中。
public class AccountType
{
[Key]
public int AccountTypeID { get; set; }
[Required]
public string AccountTypeName { get; set; }
}
public class Person
{
[Key]
public int PersonID { get; set; }
// Bunch of properties not relevant to the question here...
}
public class Account
{
[Key]
public int AccountID { get; set; }
[ForeignKey("AccountType")]
public int AccountTypeID { get; set; }
[ForeignKey("Person")]
public int PersonID { get; set; }
// A few properties here...
public virtual AccountType AccountType { get; set; }
public virtual Person Person { get; set; }
}
由于创建新帐户需要我插入帐户以及人员 table,我为这两个模型创建了一个视图模型:
public class Register
{
public Account Account { get; set; }
public Person Person { get; set; }
}
在 Register 视图中,我只是将 Account 和 Person 模型的属性绑定到表单字段。我还使用 ViewBag 在下拉列表中显示 AccountTypes 列表。
我不明白的部分在POST控制器中:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Register(Register Register)
{
if (ModelState.IsValid) {
_db.Accounts.Add(Register.Account);
_db.SaveChanges();
return View(Register);
}
// do something else
}
在项目文件中注释掉 Nullable 设置后,ModelState 检查成功通过。但是,Register.Account 具有空属性:
我在注册视图中绑定的所有值都设置正确,但我没有将导航属性(Register.Account.AccountType
和 Register.Account.Person
)绑定到任何东西,因为我不知道要绑定什么和他们一起做。
现在,我不能用上面的代码插入数据库,因为我得到一个 Person 外键约束错误。 Register.Account
的 Person
或 AccountType
导航属性似乎不能有空值。显然,必须设置它们(或者至少必须设置 Person
属性)。
我知道我可以在控制器中手动设置这些导航属性。对于 Person
,我可以在保存到数据库之前写这样的东西:Register.Account.Person = Register.Person
,我同样可以为 AccountTypes
想出一些东西来赋予它正确的值。我已经测试过了,它确实插入了数据库。
但是,我认为这不是正确的方法。在我看来,在插入数据库之前,必须有更好、更合适的方法来阐明模型或 table 与 .NET 的关系。
有人知道更好的方法吗?
P.S.: 我正在使用.NET 6.
根据 Jeremy 的建议,我通过创建一个新的视图模型解决了这个问题,它只包含我需要绑定的属性,并省略了成功插入数据库所不需要的任何导航属性。
注意:我昨天问了一个
我有三个模型:Account
、AccountType
和 Person
。我想制作一个表单页面,通过它可以将具有特定 AccountType 和特定人员信息的新帐户 POST 编辑到数据库中。
public class AccountType
{
[Key]
public int AccountTypeID { get; set; }
[Required]
public string AccountTypeName { get; set; }
}
public class Person
{
[Key]
public int PersonID { get; set; }
// Bunch of properties not relevant to the question here...
}
public class Account
{
[Key]
public int AccountID { get; set; }
[ForeignKey("AccountType")]
public int AccountTypeID { get; set; }
[ForeignKey("Person")]
public int PersonID { get; set; }
// A few properties here...
public virtual AccountType AccountType { get; set; }
public virtual Person Person { get; set; }
}
由于创建新帐户需要我插入帐户以及人员 table,我为这两个模型创建了一个视图模型:
public class Register
{
public Account Account { get; set; }
public Person Person { get; set; }
}
在 Register 视图中,我只是将 Account 和 Person 模型的属性绑定到表单字段。我还使用 ViewBag 在下拉列表中显示 AccountTypes 列表。
我不明白的部分在POST控制器中:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Register(Register Register)
{
if (ModelState.IsValid) {
_db.Accounts.Add(Register.Account);
_db.SaveChanges();
return View(Register);
}
// do something else
}
在项目文件中注释掉 Nullable 设置后,ModelState 检查成功通过。但是,Register.Account 具有空属性:
我在注册视图中绑定的所有值都设置正确,但我没有将导航属性(Register.Account.AccountType
和 Register.Account.Person
)绑定到任何东西,因为我不知道要绑定什么和他们一起做。
现在,我不能用上面的代码插入数据库,因为我得到一个 Person 外键约束错误。 Register.Account
的 Person
或 AccountType
导航属性似乎不能有空值。显然,必须设置它们(或者至少必须设置 Person
属性)。
我知道我可以在控制器中手动设置这些导航属性。对于 Person
,我可以在保存到数据库之前写这样的东西:Register.Account.Person = Register.Person
,我同样可以为 AccountTypes
想出一些东西来赋予它正确的值。我已经测试过了,它确实插入了数据库。
但是,我认为这不是正确的方法。在我看来,在插入数据库之前,必须有更好、更合适的方法来阐明模型或 table 与 .NET 的关系。
有人知道更好的方法吗?
P.S.: 我正在使用.NET 6.
根据 Jeremy 的建议,我通过创建一个新的视图模型解决了这个问题,它只包含我需要绑定的属性,并省略了成功插入数据库所不需要的任何导航属性。