asp.net-mvc - 我是否必须在 Nhibernate 中的 SaveOrUpdate 之前加载/获取实体?

标签 asp.net-mvc nhibernate asp.net-mvc-2 viewmodel valueinjecter

在我的 ASP.NET MVC 应用程序中,我将域模型与 View 模型分开。
我在 View 模型对象中转换我的实体,这样我就可以只用所需的数据“提供”我的 View (为此我使用了 valueinjecter)。
在保存过程中,我的 Controller 取回 viewmodel 对象,将其转换为域模型实体并尝试使用 SaveOrUpdate 将其持久化。
我注意到,如果我尝试更新现有记录,Nhibernate 会将其视为新对象并强制插入,即使我的实体具有正确的 ID。
我之前没有加载(获取/加载)实体,因为我想避免再次重新映射所有字段。
有什么我做错了吗?实现这一目标的最佳方法是什么?

***** - 更新 - ***

我的 Controller 接收到一个用户(ViewModel),对其进行验证并尝试通过服务层将其保存为实体:

public ActionResult Edit(Guid id, Models.User User)
{
...
var user = new Domain.User();
user.InjectFrom(User);
user.SetId(id);

user = this._SecurityService.SaveUser(user);

}

这是服务:
public Domain.User SaveUser(Domain.User User)
        {
            bool Result = false;

            if (this._ValidationEngine.IsValid(User))
            {
                using (_UnitOfWork)
                {
                    if (User.Code != Guid.Empty)
                    {
                        var user = this._UserRepository.Load(User.Code);
                        user.InjectFrom(User);
                        User = this._UserRepository.Update(user);
                    }
                    else {
                        User = this._UserRepository.Save(User);
                    }
                    Result = _UnitOfWork.Commit();
                }
            }
            return (User);
        }

我担心我必须多次转换我的 View 模型/实体。现在,当我尝试保存新用户时,我收到了这条消息:行已被另一个事务更新或删除(或未保存值映射不正确)
可能这在某些方面与达林告诉我的有关。
有没有更好的方法来做我想做的事情?

更新

我注意到错误 “行已更新或删除...” 是因为我为我的映射定义了一个版本。我能理解的是我需要拥有 编号 版本 匹配我要更新的实体。
我想了解其他人如何使用 DDD + ASP.NET MVC + NHibernate 来做这些事情???

解决方案

我所有的实体都定义了一个版本(我忘了说,对不起):
<version name="Version" type="System.Int32" unsaved-value="0">
   <column name="Version" not-null="true" />
</version>

正如 Ayende 解释的 here , Nhibernate 尝试使用如下查询更新我的实体:
UPDATE Table SET field1 = 'bla', Version = (y+1) WHERE id = x AND Version = y

其中 y 应该是我的实体的版本。由于我没有使用版本填充我的实体,因此它会生成异常 StaleObjectException。
我在我的 View 模型中添加了一个版本字段。我将它与 id 一起保存在我 View 的隐藏字段中。
我的 Controller 现在收到一个带有 Id 和版本的 View 模型。
我在我的域实体中注入(inject)这些字段并让存储库保存它(我不重新加载我的实体):
User = this._UserRepository.Update(user);

如果我收到 陈旧对象异常 异常意味着其他人已经更新了数据库行,我将为用户提供一些反馈。

最佳答案

对于 SaveOrUpdate要按预期工作,您需要明确指定 unsaved-value您的 <id> 上的属性映射。因此,例如,您将拥有:

<id unsaved-value="0" ...

然后发出 SaveOrUpdate调用 Id 属性分配给不同于 0 的值的模型它将转到UPDATE而不是 INSERT .所以要回答你的问题,不,你不需要手动发出 SELECT之前 UPDATE . SaveOrUpdate应该在幕后做这件事。

关于asp.net-mvc - 我是否必须在 Nhibernate 中的 SaveOrUpdate 之前加载/获取实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4804734/

相关文章:

asp.net-mvc - 使用 RowAction 更改 Kendo MVC 网格中的行颜色

asp.net-mvc - 如何将 ASP.Net MVC 路由段中的 1 或 0 映射到 bool 操作方法输入参数

nhibernate - 如何配置NHibernate以使用<connectionStrings>配置部分中的连接字符串

sql - NHibernate 不一致的 sql 列别名

Jquery验证器: Validate form without submiting

c# - ASP.net MVC 2.0 使用相同的表单进行添加和编辑

asp.net-mvc - ASP.NET MVC2 项目使用哪个数据网格?

asp.net-mvc - 错误。在新的 asp.net mvc4 错误中处理您的请求时发生错误,找不到 sql server?

c# - ASP.NET MVC - 关于路由中的约束

nhibernate - 如何使用 NHibernate 实现 ChangeTime 和 ChangeUser 列?