这个问题不是以代码为中心,而是一个关于习语的问题。我用脊骨/马里奥内特在前面,C#,NHibernate在后面。
我已经映射了几个表,并为创建和更新而工作。为了简单起见,假设我有两个表,一个是父表,另一个是子表,子表可能有很多行。对父的子引用是不可空的,所以我有一个逆关系,这都是有效的。从主干到Controller到NHibernate的数据流非常简单,我最后使用的是ISession.SaveOrUpdate()。如果有必要,我可以发布映射等等。我将说,Fluent NHibernate生成的映射使用父级上的一个包。
这里有一个具体的例子,说明我想要了解的情况。假设我在子表中有一个带有两行的父条目。我操作数据,以便删除其中一个子程序,但不会进行任何其他更改。Javascript发送一个对象“树”,其中包含父条目和剩下的一个子行。映射都处理得很好,但是生成的sql是一堆(不必要的,但无论如何) update语句。相反,我想要发生的是,NHibernate注意到这个新对象中只有一个子关系,但是实际数据库中有两个子对象,然后NHibernate删除另一个子对象。“级联删除孤儿”选项不起作用,因为另一个孩子实际上并不是孤儿。它仍然引用fk列中的父列,而且该列无论如何都是不可空的,这就是我使用逆映射选项的原因。
这可以在映射中设置吗?如果没有,有什么好办法来解决这种情况呢?
发布于 2015-12-07 22:17:00
由于您从客户端发送对象,然后从该对象创建实体并尝试持久化,NHibernate将不会自动删除子实体,因为它不知道子实体被删除(它只看到您只试图更新父实体和子实体),我认为这是正确的。例如,如果您只想更新父实体字段,那么必须加载整个对象图才能这样做,否则NHibernate将删除所有子对象,因为它们没有加载。
在这里您应该做的是加载父实体,删除删除的丢失子实体,然后持久化(而不是映射实体),代码应该如下所示,
void Update(ParentDto parentDto){
Parent parent = _session.Get<Parent>(parentDto.Id);
//update parent fields
var childRemoved = //find removed child from parent;
parent.Children.Remove(childRemoved);
_session.SaveOrUpdate(parent);
}
https://stackoverflow.com/questions/33900745
复制相似问题