2011-03-25 166 views
1

以下场景的正确HBM映射是什么?NHibernate映射多个关系

我需要将数据库中的ValueItem限定为收入或支出项目,以便NHibernate在加载它时将其加载到正确的列表中。

问题是:当从数据库中检索Container时,IncomeItems和ExpenseItems集合的竞争是相同的。

Design

C#

public class Container 
{ 
    public virtual IList<ValueItem> IncomeItems { get; set; } 
    public virtual IList<ValueItem> ExpenseItems { get; set; } 
} 

public class ValueItem 
{ 
    public virtual double Amount { get; set; } 
    public virtual string Description { get; set; } 
} 

HBM

<class name="Container"> 
    <id name="Id"> 
     <generator class="hilo" /> 
    </id> 

    <list name="IncomeItems " cascade="all-delete-orphan"> 
     <key column="ContainerId" /> 
     <index column="ItemIndex" /> 
     <one-to-many class="ValueItem"/> 
    </list> 

    <list name="ExpenseItems " cascade="all-delete-orphan"> 
     <key column="ContainerId" /> 
     <index column="ItemIndex" /> 
     <one-to-many class="ValueItem"/> 
    </list> 
</class> 


<class name="ValueItem"> 
    <id column="Id" type="int"> 
     <generator class="hilo" /> 
    </id> 

    <property name="Amount" /> 
    <property name="Description" /> 
</class>  
+0

看起来像它应该工作,是不是以某种方式工作或者什么你问? – R0MANARMY 2011-03-25 14:45:56

+0

@ R0MANARMY,问题是这两个列表都填充了相同的数据。 – 2011-03-25 16:31:13

回答

1

这从Don on NHUsers回答解决我的问题:

唐的回答是:

我有一个类似的映射到你,只是我使用塑料袋,而不是名单,我有逆=“真”,级联设置为默认值,我明确设置了表名,每个键的列名都不相同,并且我引用了您的容器,每个容器都有唯一的名称。也许这是反向= true或不同 列名称。

对不起,关于hokey类的名字。我在现场将它们从实际域对象名称中更改了出来,并且我感觉不太有创意。 希望这有助于

<class name="Form" > 
    <many-to-one name="CreatorPerson" class="Person" /> 
    <many-to-one name="ProcessorPerson" class="Person" /> 
</class> 

<class name="Person"> 
    <bag name="FormsCreated" inverse="true"> 
     <key> 
      <column name="CreatorPersonId" not-null="true" /> 
     </key> 
     <one-to-many class="Person" /> 
    </bag> 
    <bag name="FormsToProcess" inverse="true"> 
     <key> 
      <column name="ProcessorPerson" not-null="true" /> 
     </key> 
     <one-to-many class="Person" /> 
    </bag> 
</class> 
+0

这是行不通的。但它不是最优雅的解决方案。它为每个列表创建额外的表格。在真正的数据库设计中,只会有一个鉴别器列。 – Rafi 2015-01-05 09:27:22

0

您可以选择一个合适的继承策略: http://nhibernate.info/doc/nh/en/index.html#inheritance

或者,如果您的架构不能更改。您可以在列表映射上指定where属性。这些将指定如何获取它们。

+0

我想过用继承来解决它,但似乎把它强加到了一些并不需要它的东西上。在这种情况下,'where'子句是什么意思,这两个项目之间没有区别?我可以区分C#端但不在数据库上。可以在映射中添加具有默认值的属性,然后在那里添加默认值? – 2011-03-25 16:38:59

+0

@Philip如果没有办法在数据库端区分它,NHibernate将无法为您做到这一点。请记住它仍然是数据库的接口。 – Vadim 2011-03-25 16:47:51

+0

再次感谢您的回复。我理解你的陈述。我想知道是否有可能提供一种映射,可能类似于在NHibernate中用于子分类的鉴别器。通过子类NHibernate提供了进一步“装饰”表的能力来指示类型。显然,我不想在这里继承,因为它不是必需的。这是一种常见的模式,必须有一个简单的方法来完成这一点。顺便说一句,我知道它是一个数据库的接口。 – 2011-03-25 16:56:29