我已经搜索了这个主题,并且我发现有一个稍微相关的问题here,虽然问题听起来非常相似,但是接受的解决方案不起作用(如果有人读取评论,那么知道问题没有真正解决。)
这是我的问题,我希望有人可以提供帮助:
我有一个实体:
public class Garden
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual PlantHardinessZone Zone { get; set; }
}
它与PlantHardinessZone实体有关系:
public class PlantHardinessZone
{
public int Id { get; set; }
public string Zone { get; set; }
}
为了在DropDownListFor中轻松使用区域,我创建了一个ViewModel:
public class GardenViewModel
{
public int ZoneId { get; set; }
public IEnumerable<PlantHardinessZone> Zones { get; set; }
public Garden Garden { get; set; }
}
此ViewModel用于多个视图。它目前可用于创建新的Garden实体,但是,编辑功能不正常。如果我更改了区域,则不会在数据库中更新。我已经完成了代码,并且正在从View返回正确的区域信息,它只是没有更新。如果我更改花园的名称,那就更新了。
这是[HttpPost}编辑操作:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(GardenViewModel viewModel)
{
if (ModelState.IsValid)
{
Garden garden = viewModel.Garden;
garden.Zone = db.Zones.Where(z => z.Id == viewModel.ZoneId).Single();
db.Gardens.Attach(garden); // per the solution accepted [here][2]
db.Entry(garden).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(viewModel);
}
以下是相应的视图:
@model GardenManager.Web.ViewModels.GardenViewModel
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Garden</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Garden.Id)
<div class="form-group">
@Html.LabelFor(model => model.Garden.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Garden.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Garden.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-10 col-md-offset-2">
@Html.DropDownListFor(model => model.ZoneId,
new SelectList(Model.Zones, "Id", "Zone", Model.ZoneId),
"Select Zone", new { @class = "form-control" })
</div>
</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>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
任何人都可以帮我指导解决这个非常恼人的问题吗?所有输入欢迎和赞赏。非常感谢你!
答案 0 :(得分:0)
您正在将 Garden 的状态设置为Modified
,但这对导航属性(指向区域的链接)没有任何影响。因此,EF只会更新花园,而不会影响关联的区域。
但是,如果您将区域指定为ID
,请garden.ZoneId
,这将有效。 garden.ZoneId
是 Garden 的直接属性,它会将所有内容正确链接。
garden.ZoneId = db.Zones.Where(z => z.Id == viewModel.ZoneId).Single().Id;
总结一下:
- garden.Zone
不是对象的真实属性,它只是EF幕后处理的链接。这就是更新失败的原因
- garden.ZoneId
是对象的真实属性,因此如果您更改它,它会得到正确更新。
db.Gardens.Attach(garden);
仅附加garden
个对象。它不会附加可能与其链接的其他对象。
此外,我建议首先将实体附加到上下文,然后更改它的属性和状态。