2011-04-20 51 views
0

批准我有了這個測試代碼:編輯實體保存沒有我與NHibernate

int productId; 
{ 
    var codersAtWork = productService.Create(); 
    codersAtWork.Title = "Coders At Work"; 
    codersAtWork.Price = new Price(200, 160, 0.25m, "SEK"); 

    codersAtWork.FieldBag.ReleaseDate = new DateTime(2009, 9, 1); 
    productService.Save(codersAtWork); 
    productId = codersAtWork.Id; 
} 

ReSetUp(); // Closes and opens a new session 

{ 
    var codersAtWork = productService.GetById(productId); 
    Assert.AreEqual(new DateTime(2009, 9, 1), codersAtWork.FieldBag.ReleaseDate); 

    codersAtWork.FieldBag.ReleaseDate = "Tomorrow"; 
    Assert.Throws<InvalidFieldException>(() => { productService.Save(codersAtWork); }); 

    var cleanCode = productService.Create(); 
    cleanCode.Title = "Foo"; 
    cleanCode.Price = new Price(300, 240, 0.25m, "SEK"); 
    cleanCode.FieldBag.ReleaseDate = new DateTime(2009, 9, 1); 
    productService.Save(cleanCode); // This save will also save my incorrect product. 
} 

ReSetUp(); // Closes and opens a new session 

{ 
    var codersAtWork = productService.GetById(productId); 
    Assert.AreEqual(new DateTime(2009, 9, 1), codersAtWork.FieldBag.ReleaseDate); 
} 

我希望我的服務,以驗證我發微博,只保存它,如果它是有效的產品。但問題是,當我保存在同一會話中有效的其他內容或在會話上調用Flush時,它將被保存,而我無法控制其有效性。最後在這裏聲明將失敗。 product.FieldBag.ReleaseDate將是「明天」。

FieldBag是動態的,並保存爲Json到數據庫。但問題也適用於其他驗證。

燦NHibernate的是對

回答

4

配置)只保存項目我明確叫.SaveOrUpdate(您可以撥打Session.Evict()從會話中刪除實體。然後NHibernate將忽略對這些實體的更改。

或者,您可以使用StatelessSession來獲取/查詢它們。

0

雖然你可以使用驅逐我Session.Evict()建議考慮看看你的方法進行驗證的對象。如果我正確理解你,那麼你的productService.Save方法正在檢查傳入的對象是否有效。與其檢查某個對象對某種類型的服務管理器是否有效,您應該將該驗證移入該對象本身,並讓對象確保它永不失效。

例如:

class House 
{ 
    public Room Bedroom { get; set; } 
} 

class HouseService 
{ 
    public ValidateHouse(House aHouse) //There is no guarantee that this method is ever called 
    { 
     if (aHouse.Bedroom == null) 
     { 
      throw new InvalidFieldException(); 
     } 
    } 
} 

在上面的例子中,你不能保證ValidateHouse是不斷打來電話,爲此不能保證你有一個有效的房屋保存(或做任何事情)。

移動驗證到對象:

class House 
{ 
    private Room theBedroom; 
    public Room Bedroom 
    { 
     get 
     { 
      return theBedroom; 
     } 
     set 
     { 
      if(value == null) 
      { 
       throw new ArgumentNullException(); 
      } 
      theBedroom = value; 
     } 
    } 
} 

在這個例子中它是保證臥室永遠不會爲空。如果有人試圖將空值分配給臥室,則拋出異常並且該對象從不改變。由於該對象沒有改變NHibernate不會嘗試並堅持它。此外,這應該有利於您的整個應用程序,因爲您會知道對象始終處於有效狀態。

house.Bedroom = null; 
house.Bedroom.ToString(); //With option 1 this will throw a NullPointerException. 

house.Bedroom = null; //With option 2 this will throw an ArgumentNullException 
         //but your house object will still be in a known valid state. 
house.Bedroom.ToString(); 
相關問題