2010-04-01 47 views
0

我取得對抗如下所示的庫方法測試類:如何告訴會話拋出錯誤查詢[NHibernate]?

 public void AddFile<TFileType>(TFileType FileToAdd) where TFileType : File 
    { 
    try 
    { 
    _session.Save(FileToAdd); 
    _session.Flush(); 
    } 
    catch (Exception e) 
    { 
    if (e.InnerException.Message.Contains("Violation of UNIQUE KEY")) 
    throw new ArgumentException("Unique Name must be unique"); 
    else 
    throw e; 
    } 
    } 

     public void RemoveFile(File FileToRemove) 
    { 
    _session.Delete(FileToRemove); 
    _session.Flush(); 
    } 

,並且測試類:

  try 
    { 
    Data.File crashFile = new Data.File(); 
    crashFile.UniqueName = "NonUniqueFileNameTest"; 
    crashFile.Extension = ".abc"; 
    repo.AddFile(crashFile); 
    Assert.Fail(); 
    } 
    catch (Exception e) 
    { 
    Assert.IsInstanceOfType(e, typeof(ArgumentException)); 
    } 

    // Clean up the file 
    Data.File removeFile = repo.GetFiles().Where(f => f.UniqueName == "NonUniqueFileNameTest").FirstOrDefault(); 
    repo.RemoveFile(removeFile); 

測試失敗。當我介入跟蹤問題時,我發現當我在_session.delete()之後執行_session.flush()時,它會拋出異常,並且如果我查看它所做的sql,它實際上會提交一個「INSERT INTO」語句,這正是導致UNIQUE CONSTRAINT錯誤的SQL。我試圖封裝兩個交易,但仍然發生同樣的問題。任何人都知道原因?


編輯

其他保持不變,只增加逐出的建議

 public void AddFile<TFileType>(TFileType FileToAdd) where TFileType : File 
    { 
    try 
    { 
    _session.Save(FileToAdd); 
    _session.Flush(); 
    } 
    catch (Exception e) 
    { 
    _session.Evict(FileToAdd); 
    if (e.InnerException.Message.Contains("Violation of UNIQUE KEY")) 
    throw new ArgumentException("Unique Name must be unique"); 
    else 
    throw e; 
    } 
    } 

無差異的結果。

回答

0

NHibernate的手冊「最佳做法」第22章:

這是多了一個「最佳」實踐的必要做法。當 發生異常時,回滾ITransaction並關閉ISession。 如果你不這樣做,NHibernate不能保證內存狀態 準確表示持久狀態。作爲此特例, 不使用ISession.Load()來確定數據庫上是否存在具有給定 標識符的實例;改用Get()或查詢。

+0

好的叫AJ。這裏的問題是,我想通過整個請求使用相同的會話(init在beginrequest中,在endrequest中刪除)。所以,如果我關閉它,我該怎麼辦? – xandy 2010-04-01 16:06:33

+0

不錯的傑米。 – 2010-04-01 18:07:57

1

撥打catch塊中的_session.Evict(FileToAdd)。雖然保存失敗,但FileToAdd仍然是會話中的臨時對象,NH將在下次會話刷新時嘗試持續(插入)它。

+0

我試圖按照你所說的去提取catch中的對象。但它不起作用,它仍然嘗試在下次運行中再次插入有問題的語句! – xandy 2010-04-02 01:55:16

+0

請發佈修改後的代碼。在拋出異常之前你叫Evict嗎?附上代碼 – 2010-04-02 10:54:15

+0

。謝謝 – xandy 2010-04-02 16:08:07