我有几个这样的课程:
public class Widget
{
public string WidgetId {get; set;)
public Guid LocationId { get; set; }
public virtual Location Location { get; set; }
}
public class Location
{
public Guid LocationId { get; set; }
public string Rack { get; set; }
public string Bin { get; set; }
public virtual ICollection<Widget> Widgets { get; set; }
}
在窗口小部件的编辑视图中,我允许用户编辑位置字段,以便:
@Html.HiddenFor(item => item.LocationId)
<div class="form-group">
@Html.LabelFor(model => model.Location.Bin, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Location.Bin, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Location.Bin, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Location.Rack, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Location.Rack, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Location.Rack, "", new { @class = "text-danger" })
</div>
</div>
这是我的行动
public ActionResult Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var widget = db.Widgets.Find(id);
return View(widget);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "WidgetId,Location,LocationId")] Widget widget)
{
if (ModelState.IsValid)
{
db.Widgets.Attach(widget);
db.Locations.Attach(widget.Location);
db.Entry(widget).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(widget);
}
在Widget的Edit POST处理程序中将编辑保存到两个对象的正确方法是什么?我试着保存Widget,但是我收到一条关于无法保存重复位置的错误。
答案 0 :(得分:0)
如果你真的发布了你的行为会很有帮助,但根据你得到的错误,我可能会猜错。
当您向控制器操作发布内容时,模型绑定器会尝试将发布的内容绑定到操作接受的参数。在您的情况下,这可能是Widget
的实例,也可能是Widget
和Location
的实例。无论哪种方式,已经实例化的类看起来像类实体,因为您已经使用了您的实体类,但它们没有附加到您的实体框架上下文。因此,如果您尝试仅保存它们,Entity Framework会将它们视为全新对象,并尝试将它们保存为原样。由于您的位置具有ID,因此该ID将与现有对象的ID冲突,并且您会收到错误消息。要纠正此问题,您应该执行以下操作:
db.Locations.Attach(location);
或者
db.Entry(location).State = EntityState.Modified;
无论哪种方式,您的位置都将附加到上下文,然后将其视为更新而不是插入。
有关实体状态的详细信息,请参阅:Entity Framework Add/Attach and Entity States | MSDN