NHibernate中的逆属性


89

如何使用逆属性?如果我没记错的话,对于一对多关系,必须将inverse属性设置为true。对于多对多关系,必须将实体类逆属性之一设置为true,将另一个属性设置为false。

任何人都可以对此有所了解吗?


2
您也可以在类似问题上查看我的答案“ 何时使用inverse =“ true | false” “。
2013年

Answers:


125

逆属性不得设置为true ...

您可以使用inverse属性指定关联的“所有者”。(一个关联只能有一个所有者,因此必须将一端设置为反向,而另一端必须设置为“非反向”)。(主:inverse=false;非所有者:inverse=true

在一对多关联中,如果不将集合标记为相反端,则NHibernate将执行附加的UPDATE。实际上,在这种情况下,NHibernate首先会插入集合中包含的实体,必要时插入拥有集合的实体,然后更新“集合实体”,以便设置外键和关联制造。(请注意,这也意味着数据库中的外键应该可以为空)。

当您将集合结束标记为“反向”时,NHibernate将首先持久化“拥有”集合的实体,然后持久化集合中的实体,从而避免了其他UPDATE语句。

因此,在双向关联中,您总是有一个反向端。


4
这解释了所有添加所有者的方法都是在表中具有外键的方法
Brijesh Mishra

48
我认为这确实是一个糟糕的术语。为什么不标记所有权而不是“反向”呢?
2010年

1
+1:在已经否定的条件上使用否定:)“不得将INVERSE属性设置为true”
contactmatt 2012年

好的答案,剩下的唯一问题是如何决定谁应该是“所有者”
PandaWood 2014年

当您有一个包含两个实体之间关系的中间表时,多对多呢?
Dark_Knight,

10

除了上述答案之外,根据我的理解,您需要手动将外键值保留在集合中,也就是说,如果您不需要额外的更新语句:

Parent par = Session.Get<Parent>(8);

Child ch = new Child();
ch.Name = "Emad";

//set the parent foreign key manually
ch.MyParent = par;

par.MyChildren.Add(ch);
Session.Save(par);

有关反转属性的进一步说明,请查看以下文章:

http://www.emadashi.com/index.php/2008/08/nhibernate-inverse-attribute/


2

我可以看到“所有者”进入的位置,但是关联是一个管道,您可以向下看任何一端,因此该说哪个实体“拥有”管道了。

一种不同的看待方式是,在一对多关系中,实际上存在2个关系。

关系1:父母对许多孩子。

关系2:每个孩子和父母

因此,NH将尝试运行sql将其中的每个存储在DB中。但这不是必需的,因为在存储孩子时,例如在“关系2”中设置外键时,它也会自动修复父母与孩子之间的关系,因为“关系1”是关系2的“逆” 。

所以逆意味着,一旦我们设置了主要关系,我们就会默认得到它。即,不需要NH运行sql来修复关系1,并且通过将子级集合标记为Inverse NH,将在添加子级集合时跳过运行sql。

我假设如果您不告诉NH这是一个逆函数,那么在执行sql来尝试设置逆关系的过程中也会浪费精力-即使它不需要这样做。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.