C# NHibernate EventListener是否可以修改HasMany关系的内容?

C# NHibernate EventListener是否可以修改HasMany关系的内容?,c#,nhibernate,has-many,C#,Nhibernate,Has Many,我正在使用一个应用程序,该应用程序有几个域对象,它们自己映射到一个类似的多个域对象列表。该应用程序运行在棕地数据库之上,因此无法轻松更改结构。每个父fluent映射看起来类似于: HasMany(x => x.Locations) // Location Type applicable to the given parent .AsBag() .KeyColumn("parent_sk") .LazyLoad() .Inverse() .Casc

我正在使用一个应用程序,该应用程序有几个域对象,它们自己映射到一个类似的多个域对象列表。该应用程序运行在棕地数据库之上,因此无法轻松更改结构。每个父fluent映射看起来类似于:

HasMany(x => x.Locations)   // Location Type applicable to the given parent
    .AsBag()
    .KeyColumn("parent_sk")
    .LazyLoad()
    .Inverse()
    .Cascade.AllDeleteOrphan();
每次更改父域对象上的位置时,关联的父对象必须同步其位置属性—一些新位置已添加,一些已删除,其他位置保留在同一事务中

我已经创建并注册了一个NHibernate事件监听器,它实现了IPreUpdateEventListener、IPreInsertEventListener和IPreDeleteEventListener。当对任何位置域对象进行更改时,此事件侦听器按预期激发

一旦触发,将找到适当的父级,并操纵它们的位置集合以添加/删除位置。然后将父项发送到相应的存储库保存方法。我希望对locations集合的更改会层叠进行。但事实并非如此

调试时,我已经验证了预期值是否存在于集合中,但数据库中没有修改任何内容,也没有试图通过SHOW_SQL日志进行任何操作。如果在此过程中修改父对象上的非关系属性,则更改确实会保留在父对象上,但子对象保持不变


有没有合适的方法来配置侦听器以修改级联中HasMany的子级?

我想说,答案可以在以下问答中找到:

事实上,这是在阿耶恩德的文章中:

…然而,微妙之处来了。我们不能只更新实体状态。原因很简单,实体状态是从实体中提取出来并放在实体状态中的,我们对实体状态所做的任何更改都不会反映在实体本身中。这可能会导致数据库行和实体实例不同步,并导致一系列非常严重的问题,您不知道从哪里开始调试

以及如何解决该问题的说明:

您必须更新这两个事件侦听器中的实体和实体状态。顺便说一句,其他侦听器中的情况不一定如此

一个小的代码片段,必须根据上述需要调整以处理集合元素


因此,保持实体和实体状态的更新将是这里的解决方案。

我认为问题在于.Inverse语句。这基本上告诉NHibernate位置负责级联而不是父域对象。。。移除反转将使级联正确工作

public bool OnPreUpdate(PreUpdateEvent @event)
{
    ...
    Set(@event.Persister, @event.State, "UpdatedAt", time);
...

// the way how to assure that even the State is updated
private void Set(IEntityPersister persister, object[] state
          , string propertyName, object value)
{
    var index = Array.IndexOf(persister.PropertyNames, propertyName);
    if (index == -1)
        return;
    state[index] = value;
}