2011-02-28 105 views
3

讓我與顯示映射開始:NHibernate的級聯刪除

家長:

<bag name="Communicatiekanalen" table="COMMUNICATIEKANAAL" inverse="true" cascade="delete" lazy="true" > 
     <key column="SEK_PROFIEL"/> 
     <one-to-many class="Crm.Hibernate.Communicatiekanaal,Crm.Hibernate" /> 
</bag> 

兒童:

<many-to-one name="SekProfiel" column="SEK_PROFIEL" class="Crm.Hibernate.Profiel,Crm.Hibernate" /> 

換句話說:一個配置文件可以有多個通信通道。

在UI(用戶界面[ASP.NET Web表單])以下事件被觸發 (刪除與通信信道的簡檔連接到它):

var profielDao = CrmConfiguration.GetDaoFactory().GetProfielDao(); 
    var profiel = profielDao.GetById(2194, true); //lets say '2194' is an ID that exists 
    profielDao.Delete(profiel); 

(該DaoFactory位於在一個項目文件中,UI是一個ASP.NET網站)

此代碼有效。

重要提示:代碼使用的是NHibernate的'open-session-in-view'模式。

我有一個服務實現,觸發相同的代碼(刪除通信通道配置文件)。一些代碼...

  var daof = CrmConfiguration.GetDaoFactory(); 
      CrmSettings.Instance.UserID = user; 
      var profielDao = daof.GetProfielDao(); 

      profielDao.BeginTransaction(); 
      var profiel = profielDao.GetById(CrmEntitiesToHibernate.ParseStringToId(profileId), true); 
      profielDao.Delete(profiel); 
      profielDao.EndTransaction(); 

Where'EndTransaction()'做'commit'。我用「單元測試」測試該代碼:

[TestMethod] 
    public void TestDeleteProfile() 
    { 
     //Getting a valid NEW profile 
     var profile = GetSecundaryProfile(); 
     //Adding a communication channel to the profile 
     CrmClient.AddCommunicationChannelForProfile(GetPlainCommunicationChannel(), profile.Id, CurrentUserId); 
     //Calling the 'delete profile' method on the service --> FAIL - no cascade 
     CrmClient.DeleteProfile(profile.Id, CurrentUserId); 
    } 

此代碼失敗。以下錯誤令我煩惱:

DELETE語句與參考約束「R2_PROFIEL」的 衝突。 衝突發生在數據庫 「CRM_ontw」,表 「dbo.COMMUNICATIEKANAAL」,列 'SEK_PROFIEL'。該聲明已被終止 。

這意味着級聯根本沒有發生。從UI工作執行,而是從「服務實現」發射時,它失敗。任何想法或建議可以幫助我?

在此先感謝


編輯:以下通用的代碼刪除的對象

public void Delete(T entity) 
    { 
     try 
     { 
      OnDelete(entity); 
     } 
     catch (Exception) 
     { 
      SessionManager.Instance.RollbackTransactionOn(SessionFactoryConfigPath); 
      throw; 
     } 
     session.Delete(entity); 
    } 

設置all-delete-orphan不能解決問題。

+0

什麼'profielDao.Delete(profiel)'執行? – 2011-02-28 18:47:08

回答

0

嘗試設置cascade="delete"cascade="all-delete-orphan"

此外,還要確保在這兩種情況下,母公司正在由同一ISession實例保存。正如有人評論,我們需要看到你的方法的實施。

+0

或者將DELETE CASCADE選項應用於FK – Genius 2011-03-01 11:08:02

2

我發現了這個問題。 NHibernate的「開放式會話中視」的格局commiting更改到數據庫(請求結束這樣的情況下,會議被關閉)後關閉會話:

 finally 
     { 
      // No matter what happens, make sure all the sessions get closed 
      foreach (SessionFactoryElement sessionFactorySettings in openSessionInViewSection.SessionFactories) 
      { 
       SessionManager.Instance.CloseSessionOn(sessionFactorySettings.FactoryConfigPath); 
      } 
     } 

但我EndTransaction()實現對服務端沒有。

所以有一些調整,我創造了這個EndTransaction()方法:

public void EndTransaction() 
{ 
    try 
    { 
     SessionManager.Instance.CommitTransactionOn(SessionFactoryConfigPath); 
    } 
    finally 
    { 
     SessionManager.Instance.CloseSessionOn(SessionFactoryConfigPath); 
    } 
}