c# - 更新实体,所有更改不保存

标签 c# asp.net-mvc entity-framework c#-4.0 razor

我搜索了这个主题,发现有一个稍微相关的问题 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 在多个 View 中使用。它目前可以按预期创建新的 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);
    }

这是相应的 View :

@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")
}

任何人都可以帮助指导我解决这个非常烦人的问题吗?欢迎和赞赏所有输入。非常感谢!

最佳答案

您正在将 Garden 的状态设置为 Modified 但这对导航属性没有任何影响(指向 Zone 的链接) .因此 EF 将仅更新 Garden,而不会影响链接的 Zone

但是,如果您通过 IDZone 分配给 garden.ZoneId,那将起作用。 garden.ZoneIdGarden 的直接属性,它将正确链接所有内容。

garden.ZoneId = db.Zones.Where(z => z.Id == viewModel.ZoneId).Single().Id;

总结一下:
- garden.Zone 不是对象的真实属性,它只是 EF 在幕后处理的一个链接。这就是更新失败的原因。 - garden.ZoneId 是对象的真实属性,因此如果您更改它,它会正确更新。

db.Gardens.Attach(garden); 仅附加 garden 对象。它不会附加可能链接到它的其他对象。

此外,我建议首先将实体附加到上下文,然后更改它的属性和状态。

关于c# - 更新实体,所有更改不保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27462363/

相关文章:

c# - 在 Windows Phone 中隐藏应用程序栏

c# - 我如何模拟 Directory.GetFiles?

entity-framework - Entity Framework 兼容 POCO 的最短语法

jquery - 使用 asp.net core 删除所需的验证

Javascript Jtable 单击两次时关闭子表

asp.net - 向 User 类添加属性违反了 TContext 类型的约束

c# - 如何在 ASP .NET MVC 5.1 Web 应用程序的 Entity Framework 中使用散列 ID 以避免指向数据库中记录的可预测链接

C# 添加两个二维数组

c# - 我为 Windows Phone 7 创建的每个应用程序都出现错误

asp.net-mvc - 具有复杂子属性的 Kendo 对象的模型绑定(bind)问题