2011-02-28 89 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); 
    } 
}