C# NHibernate EventListener是否可以修改HasMany关系的内容?
我正在使用一个应用程序,该应用程序有几个域对象,它们自己映射到一个类似的多个域对象列表。该应用程序运行在棕地数据库之上,因此无法轻松更改结构。每个父fluent映射看起来类似于: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
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;
}