MVC ASP.NET 创建在单个视图中关联的两个模型
MVC ASP.NET Creating two models that are associated in a single view
我正在使用 ASP.NET,我有两个模型,Contact 和 Customer,两者之间存在一对一的关系。因此,每个联系人都将添加到联系人实体中,当联系人是客户时,额外的信息将添加到客户实体中。
我创建了一个包含两者的 ViewModel。然后在 post 请求中传递视图模型时,我首先添加联系人,它添加正确,然后我想添加与前一个联系人有关系的客户,但我不知道该怎么做.
[HttpPost]
public ActionResult CustomerCreate(CustomerViewModel customerViewModel)
{
if (ModelState.IsValid)
{
try
{
using (var db = new ModelContactContainer())
{
db.Contact.Add(customerViewModel.contact);
customerViewModel.customer.Contact = customerViewModel.contact;
db.Customer.Add(customerViewModel.customer);
db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return CustomerCreate();
}
}
return CustomerCreate();
}
更新
这些是我的模型的 类:
Contact.cs
using System;
using System.Collections.Generic;
public partial class Contact
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Customer Customer { get; set; }
}
Customer.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class Customer
{
public int Id { get; set; }
public string Something { get; set; }
[Required]
public virtual Contact Contact { get; set; }
}
CustomerViewModel.cs
public class CustomerViewModel
{
public Contact contact { get; set; }
public Customer customer { get; set; }
}
这是风景
CustomerCreate.cshtml
@model W3SchoolsApplication.Models.CustomerViewModel
@{
ViewBag.Title = "Create Customer";
}
<h2>@ViewBag.Title</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.contact.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.contact.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.contact.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.customer.Something, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.customer.Something, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.customer.Something, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
我不确定,但也许您应该更改顺序并且您可能不必显式添加联系人:
customerViewModel.customer.Contact = customerViewModel.contact;
db.Contact.Add(customerViewModel.customer);
db.SaveChanges();
您必须了解幕后发生的事情才能理解为什么这不起作用。
using (var db = new ModelContactContainer())
{
db.Contact.Add(customerViewModel.contact);
db.SaveChanges(); // so the above has an ID and the foreign key relationship works
// this doesn't add anything to the database, it just populates the foreign key relationship
customerViewModel.customer.Contact = customerViewModel.contact;
db.Customer.Add(customerViewModel.customer);
db.SaveChanges();
}
如果您希望整个操作是原子的,您必须将其包装在事务中,如下所示:
using (var db = new ModelContactContainer())
using (var transaction = db.Database.BeginTransaction())
{
db.Contact.Add(customerViewModel.contact);
db.SaveChanges();
customerViewModel.customer.Contact = customerViewModel.contact;
db.Customer.Add(customerViewModel.customer);
db.SaveChanges();
transaction.Commit();
}
我正在使用 ASP.NET,我有两个模型,Contact 和 Customer,两者之间存在一对一的关系。因此,每个联系人都将添加到联系人实体中,当联系人是客户时,额外的信息将添加到客户实体中。
我创建了一个包含两者的 ViewModel。然后在 post 请求中传递视图模型时,我首先添加联系人,它添加正确,然后我想添加与前一个联系人有关系的客户,但我不知道该怎么做.
[HttpPost]
public ActionResult CustomerCreate(CustomerViewModel customerViewModel)
{
if (ModelState.IsValid)
{
try
{
using (var db = new ModelContactContainer())
{
db.Contact.Add(customerViewModel.contact);
customerViewModel.customer.Contact = customerViewModel.contact;
db.Customer.Add(customerViewModel.customer);
db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return CustomerCreate();
}
}
return CustomerCreate();
}
更新
这些是我的模型的 类:
Contact.cs
using System;
using System.Collections.Generic;
public partial class Contact
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Customer Customer { get; set; }
}
Customer.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class Customer
{
public int Id { get; set; }
public string Something { get; set; }
[Required]
public virtual Contact Contact { get; set; }
}
CustomerViewModel.cs
public class CustomerViewModel
{
public Contact contact { get; set; }
public Customer customer { get; set; }
}
这是风景
CustomerCreate.cshtml
@model W3SchoolsApplication.Models.CustomerViewModel
@{
ViewBag.Title = "Create Customer";
}
<h2>@ViewBag.Title</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.contact.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.contact.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.contact.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.customer.Something, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.customer.Something, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.customer.Something, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
我不确定,但也许您应该更改顺序并且您可能不必显式添加联系人:
customerViewModel.customer.Contact = customerViewModel.contact;
db.Contact.Add(customerViewModel.customer);
db.SaveChanges();
您必须了解幕后发生的事情才能理解为什么这不起作用。
using (var db = new ModelContactContainer())
{
db.Contact.Add(customerViewModel.contact);
db.SaveChanges(); // so the above has an ID and the foreign key relationship works
// this doesn't add anything to the database, it just populates the foreign key relationship
customerViewModel.customer.Contact = customerViewModel.contact;
db.Customer.Add(customerViewModel.customer);
db.SaveChanges();
}
如果您希望整个操作是原子的,您必须将其包装在事务中,如下所示:
using (var db = new ModelContactContainer())
using (var transaction = db.Database.BeginTransaction())
{
db.Contact.Add(customerViewModel.contact);
db.SaveChanges();
customerViewModel.customer.Contact = customerViewModel.contact;
db.Customer.Add(customerViewModel.customer);
db.SaveChanges();
transaction.Commit();
}