C# NHibernate-侦听器未应用于级联子级
我对Nhibernate和一个非常简单的亲子关系有以下问题 我有三个侦听器:保存、更新和删除。如果要持久化的对象实现了IAuditCreate接口,我将分配CreatedDate字段 我的父映射C# NHibernate-侦听器未应用于级联子级,c#,nhibernate,cascade,C#,Nhibernate,Cascade,我对Nhibernate和一个非常简单的亲子关系有以下问题 我有三个侦听器:保存、更新和删除。如果要持久化的对象实现了IAuditCreate接口,我将分配CreatedDate字段 我的父映射 <hibernate-mapping assembly="Model" namespace="Model" xmlns="urn:nhibernate-mapping-2.2"> <class name="SecSession" table="SEC_SESSION" lazy="
<hibernate-mapping assembly="Model" namespace="Model" xmlns="urn:nhibernate-mapping-2.2">
<class name="SecSession" table="SEC_SESSION" lazy="true" >
<id name="SecSessionId">
<column name="SEC_SESSION_ID" sql-type="bigint" not-null="true" />
<generator class="identity" />
</id>
<property name="CreatedDate">
<column name="CREATED_DATE" sql-type="datetime" not-null="true" />
</property>
<bag name="SecSessionLogs" inverse="true" cascade="all-delete-orphan" >
<key column="SEC_SESSION_ID" />
<one-to-many class="SecSessionLog" />
</bag>
</class>
</hibernate-mapping>
我没有显式地发送SecSessionLog进行保存,正如映射所示:CASCADE=ALL-DELETE-ORPHAN
因此,这里的问题是,没有为子日志对象调用侦听器,因此CreatedDate字段为空,并且我在数据库中得到一个null值异常
映射中是否缺少要配置的内容?在听众中
非常感谢您的帮助
谢谢大家我也在应用程序中使用层叠。在我的例子中,我需要截取命令“insert”、“delete”和“update”,以确保在执行的操作范围内只保留实体的特定子集 在我的例子中,以下事件起作用:
IPreInsertEventListener
,IPreUpdateEventListener
,IPreDeleteEventListener
我之前的答案是错误的强>
正确答案:
您不能使用“IPreInsertEventListener”,此时更改实体的属性无效。这样做是因为NHibernate已经捕获了将用于运行SQL命令的数据。我已经测试过了
我希望很快得到答复
但我认为您的问题应该涉及以下侦听器:“合并”、“保存更新”、“保存”、“更新”、“预收集重新创建”、“预收集删除”和“预收集更新”
我以前的答案又错了强>
我已经测试并发现,使用上面列出的事件*需要大量的编码,而且我无法在“SecSession”中使用“merge”,然后插入和更新级联到“SecSessionLogs”中
有一种方法可以在监听器内修改后切换回NHibernate属性值
*“合并”、“保存更新”、“保存”、“更新”、“预收集重新创建”、“预收集删除”和“预收集更新”
此代码显示:
会话日志:
#|SEC_SESSION_LOG_ID|LOG_MESSAGE |CREATED_DATE |SEC_SESSION_ID
-+------------------+-------------+----------------+--------------
1|1 |LOG_MESSAGE_1|2012-07-10 16:53|1
2|2 |LOG_MESSAGE_2|2012-07-11 16:53|2
3|3 |LOG_MESSAGE_3|2012-07-12 16:53|3
4|4 |LOG_MESSAGE_4|2012-07-13 16:53|4
我正在使用:
- NHibernate 3.2.0
- System.Data.SQLite 1.0.80.0
- 在打开解决方案(“.\Src\SofPOC.2010.sln”)之前,请运行“.\Dependencies\setup.bat”以加载依赖项
- 有关依赖项的说明,请参阅“\readme.txt”和“\dependencies\readme.txt”
IPreInsertEventListener
和IPreUpdateEventListener
,两者都没有被调用。我在球场上没有进球。看起来验证在事件侦听器之前运行。。。
using (var dataSession = DataStore.OpenDataSession())
using (var transaction = dataSession.BeginTransaction())
{
var id = (PK)dataSession.Save(secSession);
transaction.Commit();
return id;
}
public class AuditCreateListener : IPreInsertEventListener, IPreUpdateEventListener
{
public bool OnPreInsert(PreInsertEvent @event)
{
return this.OnEventCommon(
@event,
new Action<object[]>(
delegate(Object[] newState)
{
newState.CopyTo(@event.State, 0);
}));
}
public bool OnPreUpdate(PreUpdateEvent @event)
{
return this.OnEventCommon(
@event,
new Action<object[]>(
delegate(Object[] newState)
{
newState.CopyTo(@event.State, 0);
}));
}
private bool OnEventCommon(AbstractPreDatabaseOperationEvent @event, Action<object[]> setStateCallback)
{
IAuditCreate auditCreate = @event.Entity as IAuditCreate;
if (auditCreate != null && auditCreate.CreatedDate == null)
{
auditCreate.CreatedDate = DateTime.Now;
if (setStateCallback != null)
{
Object[] newState = @event.Persister.GetPropertyValues(auditCreate, EntityMode.Poco);
setStateCallback(newState);
}
}
return false;
}
}
#|SEC_SESSION_ID|CREATED_DATE
-+--------------+----------------
1|1 |2012-07-10 16:53
2|2 |2012-07-11 16:53
3|3 |2012-07-12 16:53
4|4 |2012-07-13 16:53
#|SEC_SESSION_LOG_ID|LOG_MESSAGE |CREATED_DATE |SEC_SESSION_ID
-+------------------+-------------+----------------+--------------
1|1 |LOG_MESSAGE_1|2012-07-10 16:53|1
2|2 |LOG_MESSAGE_2|2012-07-11 16:53|2
3|3 |LOG_MESSAGE_3|2012-07-12 16:53|3
4|4 |LOG_MESSAGE_4|2012-07-13 16:53|4