7

我已經從視圖模型中分離了域模型。
我在一個視圖模型對象中轉換我的實體,這樣我就可以只用需要的數據「饋送」我的視圖(爲此使用了valueinjecter)。
在保存過程中,我的控制器取回viewmodel對象,將其轉換爲域模型實體,並嘗試使用SaveOrUpdate保存它。 我注意到,如果我嘗試更新現有記錄,Nhibernate認爲它是一個新對象並強制INSERT,即使我的實體具有正確的ID。
我之前沒有加載(獲取/加載)實體,因爲我希望避免重新映射所有的字段。
有什麼我做錯了嗎?達到這個目標的最佳方法是什麼?是否必須在Nhibernate的SaveOrUpdate之前加載/獲取實體?我的ASP.NET MVC應用程序中的

***** - UPDATE - ***

我的控制器接收一個用戶(視圖模型),驗證它並試圖通過服務層保存它作爲一個實體:

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

我有一個問題,我必須轉換我的viewmodel /實體很多次的事實。現在,當我嘗試保存新用戶時,我收到此消息:行被其他事務更新或刪除(或未保存的值映射不正確)
也許這在某種程度上與Darin告訴我的內容有關。
有沒有更好的方法來做我想做的事情?

UPDATE

我注意到錯誤「行被更新或者刪除...」是事實,我爲我的映射定義的版本引起的。我可以理解的是我需要Id版本匹配我想要更新的實體。
我想了解其他人如何使用DDD + ASP.NET MVC + NHibernate做這些事情?

SOLUTION

我所有的實體版本定義(我忘了說了,不好意思):

<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。
我已經添加了一個版本字段到我的viewmodel。我將它與id一起保存在我的視圖的隱藏字段中。
我的控制器現在接收一個帶有Id和版本的視圖模型。 我在域實體注入這些領域,讓庫保存它(我不重裝我的實體):

User = this._UserRepository.Update(user); 

如果我得到一個StaleObjectException異常例外,這意味着別人已經更新了DB行我會向用戶提供一些反饋。

+0

嘗試加載實體,並重新映射後(我知道你不想這樣),只是試試這個,告訴我們它是否以這種方式工作 – Omu 2011-01-27 07:46:17

+0

我想我的問題是與版本。我的在我的映射中定義了 LeftyX 2011-01-27 11:14:04

回答

0

由於您已有一個ID,因此知道這是更新,請使用session.Update而不是SaveOrUpdate

4

要使SaveOrUpdate正常工作,您需要在<id>映射中明確指定unsaved-value屬性。因此,例如,你會:

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

,然後在具有分配給除0不同的值Id屬性的模型發出SaveOrUpdate呼叫,它要UPDATE而不是INSERT。因此,要回答您的問題,不,您不需要在UPDATE之前手動發出SELECTSaveOrUpdate應該在幕後做到這一點。

+0

Thanks Daring。我想我必須使用空的Guid(00000000-0000-0000-0000-000000000000),如果我的ID是Guid類型的,對吧? – LeftyX 2011-01-26 13:26:48

相關問題