【发布时间】:2018-04-01 11:51:00
【问题描述】:
我已经创建了一个复杂的模型,并且一直在努力寻找一种将表单数据添加/更新到数据库的方法。
基本上我的模型如下所示:
namespace Models
{
public class ModelClass1
{
public int Id { get; set; }
public string Prop1 { get; set; }
public string Prop2 { get; set; }
public ICollection<ModelClass2> ModelClass2 { get; set; }
}
public class ModelClass2
{
public int Id { get; set; }
public string Prop3 { get; set; }
public string Prop4 { get; set; }
public ICollection<ModelClass3> ModelClass3 { get; set; }
}
public class ModelClass3
{
public int Id { get; set; }
public string Prop5 { get; set; }
public string Prop6 { get; set; }
}
}
我为 ModelClass1 创建了一个脚手架 CRUD 控制器,并尝试使用一个 Edit 类更新所有 3 个实体。
我的编辑(获取/发布)类:
// GET
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ModelClass1 ModelClass1 = db.ModelClass1
.Include(i => i.ModelClass2.Select(c => c.ModelClass3))
.Where(x => x.Id == id)
.Single();
if (config == null)
{
return HttpNotFound();
}
return View(ModelClass1);
}
// POST
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ModelClass1 ModelClass1)
{
if (ModelState.IsValid)
{
db.Entry(ModelClass1).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(ModelClass1);
}
我选择使用编辑器模板来填充编辑视图中的表单,因此 Edi.cshtml 将如下所示:
@model ModelClass1
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)
<div class="form-group">
@Html.LabelFor(model => model.Prop1, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Prop1, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Prop1, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Prop2, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Prop2, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Prop2, "", new { @class = "text-danger" })
</div>
</div>
@Html.EditorFor(model => model.ModelClass2, new { htmlAttributes = new { @class = "form-control" } })
@Html.EditorFor(model => model.ModelClass2.FirstOrDefault().ModelClass3, new { htmlAttributes = new { @class = "form-control" } })
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
}
并为我的 3 个模型类中的每一个创建了类似于下面的模板:
@model ModelClass2
<div class="form-group">
@Html.LabelFor(model => model.Prop3, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Prop3, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Prop3, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Prop4, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Prop4, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Prop4, "", new { @class = "text-danger" })
</div>
</div>
数据显示正确,然后我调用 Edit 控制器,但是当我修改表单中的数据并发布它调用 HTTPPost Edit 方法时,我收到以下错误:
附加类型为“ModelClass3”的实体失败,因为同一类型的另一个实体已经具有相同的主键值。如果图中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新实体,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图形,然后根据需要将非新实体的状态设置为“未更改”或“已修改”。
如果我从控制器/视图中完全删除 ModelClass3,我不会收到任何错误,但修改后的数据不会保存到数据库中。
我很确定我的方法不是最好的,所以任何帮助都将不胜感激,因为我的想法已经不多了。
【问题讨论】:
标签: c# asp.net-mvc entity-framework asp.net-mvc-4