NHibernate映射多对多连接表

时间:2009-05-19 09:53:37

标签: nhibernate nhibernate-mapping

我的数据库结构如下所示:

Person
  Id
  Name
  FieldA
  FieldB

Phone
  Id
  Number

PersonPhone
  PhoneId
  PersonId
  IsDefault

我的人物和电话对象的NHibernate映射是直截了当的,它的PersonPhone我很难用。我希望将PersonPhone对象的集合作为Person的属性,这将允许我拥有一个人的电话号码,并能够告诉一个人的“默认”或主要电话号码。

理想情况下我的PersonPhone对象就像这样:

public class PersonPhone
{
    public virtual Person Person { get; set; }
    public virtual Phone Phone { get; set; }
    public virtual bool IsDefault { get; set; }
}

到目前为止,我对此表的NHibernate映射如下所示:

<class name="PersonPhone" table="PersonPhone">
    <composite-id>
        <key-property name="Person" column="PersonId" />
        <key-property name="Phone" column="PhoneId" />
    </composite-id>
    <property name="IsDefault" column="IsDefault"/>
</class>

但是当NHibernate编译我的映射时,我得到一个错误说:

无法编译映射文档:MyApp.Entities.PersonPhone.hbm.xml。 NHibernate.MappingException:无法确定以下类型:MyApp.Entities.Person,MyApp.Entities,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null,对于列:NHibernate.Mapping.Column(PersonId)

关于如何映射它的任何想法?

3 个答案:

答案 0 :(得分:6)

答案是使用复合键中的元素而不是键属性

<class name="PersonPhone" table="PersonPhone">
    <composite-id>
        <key-many-to-one name="Person" column="PersonId"></key-many-to-one>
        <key-many-to-one name="Phone" column="PhoneId"></key-many-to-one>
    </composite-id>
    <property name="IsDefault" column="IsDefault"/>
</class>

答案 1 :(得分:3)

我认为考虑Phone和Peron实体之间的多对多关系并摆脱PersonPhone实体更合适。

答案 2 :(得分:3)

要使用Fluent NHibernate设置相同的映射,请执行以下操作:

public class PersonPhoneMap : ClassMap<PersonPhone>
{
    public PersonPhoneMap()
    {
        CompositeId()
            .KeyReference(p => m.Person)
            .KeyReference(p => m.Phone);

        References(p => p.Person)
            .Column("PersonID");
        References(m => m.Phone)
            .Column("PhoneID");
        Map(p => p.IsDefault)
            .Column("IsDefault");
    }
}