Asp.net mvc 4 在Asp.net MVC4中使用NHibernate更新对象

Asp.net mvc 4 在Asp.net MVC4中使用NHibernate更新对象,asp.net-mvc-4,nhibernate,Asp.net Mvc 4,Nhibernate,我在ASP.NETMVC4中用nhibernate更新对象时遇到问题 我正在执行此场景中的更新: the application loads an object in the first session the object is passed up to the UI tier some modifications are made to the object the object is passed back down to the business logic tier the a

我在ASP.NETMVC4中用nhibernate更新对象时遇到问题 我正在执行此场景中的更新:

the application loads an object in the first session

the object is passed up to the UI tier

some modifications are made to the object

the object is passed back down to the business logic tier

the application persists these modifications by calling SaveOrUpdate()
所有这些都只发生在一个会话中。我有一个静态类名NHibernateSessionPerRequest 它的构造函数是静态的(Singleton)

但是菜单ID是零。并且没有其原始ID(ID是GUID的类型)。SaveOrUpdate()总是将其视为新对象并保存,而不是更新

这里是Edit.cshtml:

    @model MyApp.Domain.Entities.MenuComponent

@{
    ViewBag.Title = "Edit";
    Layout = "~/Views/Shared/_AdminLayout.cshtml";
}

<h2>Edit @Model.Name
</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>MenuComponent</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Description)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Description)
            @Html.ValidationMessageFor(model => model.Description)
        </div>
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>
@model MyApp.Domain.Entities.MenuComponent
@{
ViewBag.Title=“编辑”;
Layout=“~/Views/Shared/_AdminLayout.cshtml”;
}
编辑@Model.Name
@使用(Html.BeginForm()){
@Html.ValidationSummary(true)
菜单组件
@LabelFor(model=>model.Name)
@EditorFor(model=>model.Name)
@Html.ValidationMessageFor(model=>model.Name)
@LabelFor(model=>model.Description)
@EditorFor(model=>model.Description)
@Html.ValidationMessageFor(model=>model.Description)

} @ActionLink(“返回列表”、“索引”)

如何更新对象?

从您发布的内容来看,似乎您正在将实体返回到视图,并且没有使用任何视图模型概念

首先 通常,实体是用私有setter定义的,如果您使用实体本身,私有setter将阻止id发回编辑操作

第二(我对此不确定)


由于您要在post中获取对象并使用每个请求的会话(假设是因为它非常常见),nhibernate可能会将其视为一个新实体。我对第二点非常怀疑,但将尝试重新创建该点,并根据您发布的内容更新答案。您似乎正在将实体返回到视图,并且没有使用任何视图模型概念

首先 通常,实体是用私有setter定义的,如果您使用实体本身,私有setter将阻止id发回编辑操作

第二(我对此不确定)


由于您要在post中获取对象并使用每个请求的会话(假设是因为它非常常见),nhibernate可能会将其视为一个新实体。我对第二点非常怀疑,但将尝试重新创建此点并更新答案。根据您的评论,我发现两个问题:

  • 似乎您已经从标记中删除了
    @Html.HiddenFor(model=>model.ID)
    。你应该把它放回原处,否则你的ID将不会存储在页面中,而不会发布回你的控制器
  • 您的
    ID
    代码是
    public virtual Guid ID{get;private set;}
    您应该删除setter上的
    private
    修饰符。我猜这会阻止ModelBinder在接收发布的数据时设置属性

从您的评论中,我看到两个问题:

  • 似乎您已经从标记中删除了
    @Html.HiddenFor(model=>model.ID)
    。你应该把它放回原处,否则你的ID将不会存储在页面中,而不会发布回你的控制器
  • 您的
    ID
    代码是
    public virtual Guid ID{get;private set;}
    您应该删除setter上的
    private
    修饰符。我猜这会阻止ModelBinder在接收发布的数据时设置属性

如何将存储在视图中的ID发回?你能为这个字段贴上标记吗?在视图中你有@Model.HiddenFor(x=>x.Id)@rippo是的,我有@Html.HiddenFor(Model=>Model.Id),但是删除它并不能解决问题。你应该把
@Html.HiddenFor(Model=>Model.Id)
放回你的代码中,并删除
public virtual Guid ID{get;private set;}
中setter上的
private
修饰符,这将防止绑定ViewModel@jbl你是一个伟大而聪明的人。你救了我的命。只需发布您的答案即可将其标记为救生答案。如何将存储在视图中的ID发回?你能为这个字段贴上标记吗?在视图中你有@Model.HiddenFor(x=>x.Id)@rippo是的,我有@Html.HiddenFor(Model=>Model.Id),但是删除它并不能解决问题。你应该把
@Html.HiddenFor(Model=>Model.Id)
放回你的代码中,并删除
public virtual Guid ID{get;private set;}
中setter上的
private
修饰符,这将防止绑定ViewModel@jbl你是一个伟大而聪明的人。你救了我的命。我有一个抽象类名为Entity,我所有的类都是Entity的子类。在Entity中,我定义了如下Id属性:public virtual Guid Id{get;private set;}当用户的浏览器打开并浏览我的站点时,web应用程序只创建一个会话并使用它。所以并没有任何新的sessionI有一个名为Entity的抽象类,我所有的类都是从Entity派生的。在Entity中,我定义了如下Id属性:public virtual Guid Id{get;private set;}当用户的浏览器打开并浏览我的站点时,web应用程序只创建一个会话并使用它。所以没有任何新的会话
    @model MyApp.Domain.Entities.MenuComponent

@{
    ViewBag.Title = "Edit";
    Layout = "~/Views/Shared/_AdminLayout.cshtml";
}

<h2>Edit @Model.Name
</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>MenuComponent</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Description)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Description)
            @Html.ValidationMessageFor(model => model.Description)
        </div>
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>