Do I have to Load/Get an entity before SaveOrUpdate in Nhibernate?

in my ASP.NET MVC application I've separated the domain model from the view model.
I transform my entity in a viewmodel object so I can "feed" my views with only the data needed (I used valueinjecter for this purpose).
During the save process my controller gets back the viewmodel object, transforms it into a domain model entity and try to persist it with SaveOrUpdate. I've noticed that if I try to update an existing record, Nhibernate considers it as a new object and forces an INSERT, even if my entity has a proper ID.
I haven't loaded (Get/Load) the entity before cause I would like to avoid to re-map all the fields again.
Is there anything I am doing wrong? What's the best way to achieve that?

***** - UPDATE - ***

My controller receives a User (ViewModel), validates it and tries to save it through a service layer as an entity:

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

user = this._SecurityService.SaveUser(user);

}

This is the service:

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);
        }

I've got a concern about the fact that I have to transform my viewmodel/entity so many times. Now when I try to save a new User I got this message: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)
Probably this is in some ways related to what Darin was telling me.
Are there any better ways to do what I am trying to do?

UPDATE

I've noticed that the error "Row was updated or deleted..." is caused by the fact that I have a version defined for my mappings. What I can understand is I need to have the Id and the version matching the entity I want to update.
I would like to understand how other people do these things with DDD + ASP.NET MVC + NHibernate ???

SOLUTION

All my entities have a version defined (I forgot to say, sorry):

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

As Ayende explained here, Nhibernate tries to update my entity with a query like this:

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

where y should be the version of my entity. Since I wasn't populating my entity with a version, it would generate an exception StaleObjectException.
I've added a version field to my viewmodel. I save it in a hidden field of my view together with the id.
My controller now receives a viewmodel with an Id and a version. I inject these fields in my domain entity and let the repository save it (I don't reload my entity):

User = this._UserRepository.Update(user);

If I get a StaleObjectException exception it means that someone else has updated the DB row and I'll provide the user with some feedback.


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


For SaveOrUpdate to work as expected you need to explicitly specify the unsaved-value attribute on your <id> mapping. So for example you would have:

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

and then issue a SaveOrUpdate call on a model which has the Id property assigned to a value different than 0 and it is going to UPDATE instead of INSERT . So to answer your question, no, you don't need to manually issue a SELECT before UPDATE . SaveOrUpdate should do this behind the scenes.

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

上一篇: GLSL

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