是否必须在Nhibernate的SaveOrUpdate之前加载/获取实体?

在我的ASP.NET MVC应用程序中,我将视域模型与视图模型分开。
我在一个视图模型对象中转换我的实体,这样我就可以仅用需要的数据“馈送”我的视图(为此我使用了valueinjecter)。
在保存过程中,我的控制器取回viewmodel对象,将其转换为域模型实体并尝试使用SaveOrUpdate保存它。 我注意到,如果我尝试更新现有记录,Nhibernate会将其视为新对象并强制执行INSERT,即使我的实体具有正确的ID也是如此。
我之前没有加载(获取/加载)实体,因为我希望避免重新映射所有字段。
有什么我做错了吗? 达到这个目标的最佳方法是什么?

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

我的控制器收到一个User(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);
        }

我担心我必须多次转换视图模型/实体。 现在,当我尝试保存新用户时,我收到了以下消息: 行被更新或被另一个事务删除(或未保存的值映射不正确)
或许这在某种程度上与Darin告诉我的有关。
有没有更好的方法去做我想做的事情?

UPDATE

我注意到错误“Row was updated or deleted ...”是由于我有一个为我的映射定义的版本。 我可以理解的是,我需要让Id版本匹配我想要更新的实体。
我想了解其他人如何用DDD + ASP.NET MVC + NHibernate做这些事情?

我的所有实体都有一个定义的版本(我忘了说,对不起):

<version name="Version" type="System.Int32" unsaved-value="0">
   <column name="Version" not-null="true" />
</version>

正如Ayende在这里解释的那样,Nhibernate试图用这样的查询来更新我的实体:

UPDATE Table SET field1 = 'bla', Version = (y+1) WHERE id = x AND Version = y

y应该是我实体的版本。 由于我没有用一个版本填充我的实体,它会产生一个异常StaleObjectException。
我已经为我的viewmodel添加了一个版本字段。 我将它与id一起保存在我的视图的隐藏字段中。
我的控制器现在接收一个带有Id和版本的视图模型。 我将这些字段注入到我的域实体中,并让存储库保存它(我不重装我的实体):

User = this._UserRepository.Update(user);

如果我得到一个StaleObjectException异常,这意味着别人已经更新了数据库行,我会向用户提供一些反馈。


由于您已经拥有一个Id,因此知道这是一个更新,请使用session.Update而不是SaveOrUpdate


要使SaveOrUpdate按预期工作,您需要在<id>映射中明确指定unsaved-value属性。 举例来说,您将拥有:

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

然后对Id属性分配的值不是0的模型发出SaveOrUpdate调用,并且它将UPDATE而不是INSERT 。 所以要回答你的问题,不,你不需要在UPDATE之前手动发出SELECTSaveOrUpdate应该在幕后执行此操作。

链接地址: http://www.djcxy.com/p/50263.html

上一篇: Do I have to Load/Get an entity before SaveOrUpdate in Nhibernate?

下一篇: Mysql Stored Procedures Column Type Reference