2014-03-28 141 views
2

所以,就在上周我问了一个关于如何处理many-to-many with extra columns nhibernate的问题。答案似乎很清楚,只是使用链接表,并使两个多对一。但是,因为我使用Entity Developer来生成我的模型,所以我遇到了该方法的问题...NHibernate不保存复合数据实体

无论如何,我继续调查了多对多问题,发现也许我可以创建一些一种复合元素,将起到非常像许多到多,但有一个额外的属性

这将是新的模式(!): Model

用户映射文件看起来像这样:

<hibernate-mapping ...> 
    <class name="User" table="Users"> 
    <id name="UId" type="Int32">...</id> 
    <property name="UserName" type="String">...</property> 

    <set name="Groups" table="UGLinks" inverse="true" generic="true"> 
     <key> 
     <column name="UId" /> 
     </key> 
     <composite-element class="UGLinkExtra"> 
     <many-to-one name="Groups" class="Group" fetch="join"> 
      <column name="GId" /> 
     </many-to-one> 
     <property name="Date"> 
      <column name="Date" not-null="true" /> 
     </property> 
     </composite-element> 
    </set> 

    </class> 
</hibernate-mapping> 

所以我有这种Composite-element这种模拟多对多的外观,但具有额外的列属性。

比方说,我有一个User u和一个Group g,我想链接。然后,它只是一个(其中包括g如果我做u.Groups我得到一个列表(UGLinkExtra的))

u.Groups.add(new UGLinkExtra() {Groups = g, Date = DateTime.Now}); 

而在NHibernate的我也看到一个链接已添加的事情,不过,我可以”不要将它保存到数据库! 即使当我做session.SaveOrUpdate(u)(或G,我曾经尝试都),它永远不会被写入数据库...只有SQL我看到的是:

NHibernate: SELECT this_.UId as UId0_0_, this_.UserName as UserName0_0_ FROM Users this_ 
NHibernate: SELECT this_.GId as GId2_0_, this_.GroupName as GroupName2_0_ FROM Groups this_ 

回答

2

这里的问题涉及<set>的设置。你告诉NHiberante <set name="Groups" ... inverse="true"这意味着:NHibernate,不要坚持这个集合的项目。这些都是如此聪明,以至于他们会坚持自己......

如果我们使用<one-to-many>映射,通常可以这样。但是<composite-element>完全依赖于它的父集合来管理其写操作。因此,改变映射inverse="false"

<set name="Groups" table="UGLinks" inverse="false" ... 
+0

嗯好了,这工程,然后我发现我只能添加组到用户,或者周围的其他方法(取决于'inverse'选项)。无论如何可以添加两者吗? – Markus

+0

我刚才试着解释一样在这里http://stackoverflow.com/questions/22824660/。我*(只有我的,但非常强大)*意见是,用*第一级公民*'PairingEntity'代替'多对多'。将其与标准的一对多和多对一的元素进行映射,并且......仅仅获得利润。你可以在这里尝试......你可以找到自己的方式,(我也尝试过);但是一旦可以改变方法......它会变得更容易...... –

+0

其实我的hbm生成器有问题('Entity开发者')所以我不能用2 * Many-to-One方法创建一个从用户到用户(多对多)的链接。 (我需要这个:http://stackoverflow.com/a/504845/1140368),但无法找到生成它的方法。所以,因为这种方法正常工作,我打算使用它,只是我似乎无法再次删除链接...任何想法?尝试'myUser.Managers.Remove(new UULinkExtra(){Manager = myManager});' – Markus