NHibernate映射多对多连接表

时间:2022-10-05 11:29:30

My database structure looks something like this:

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

Person
  Id
  Name
  FieldA
  FieldB

Phone
  Id
  Number

PersonPhone
  PhoneId
  PersonId
  IsDefault

My NHibernate mappings for the Person and Phone objects are straight forward, its the PersonPhone I'm having difficult with. I want to have a collection of PersonPhone objects as a property of Person which will allow me to have the Phone number of a person and be able to tell which is the "default" or primary phone number for a person.

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

ideally Id like my PersonPhone object to look like this:

理想情况下我喜欢我的PersonPhone对象看起来像这样:

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

so far my NHibernate mapping for this table looks like the following:

到目前为止,我对此表的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>

but when NHibernate compiles my mappings I get an error saying:

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

Could not compile the mapping document: MyApp.Entities.PersonPhone.hbm.xml. NHibernate.MappingException : Could not determine type for: MyApp.Entities.Person, MyApp.Entities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null, for columns: NHibernate.Mapping.Column(PersonId)

无法编译映射文档: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)

Any ideas on how this should be mapped?

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

3 个解决方案

#1


The answer is to use the element in your composite key rather than the key-property

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

<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>

#2


I think It is more proper to consider Many-to-Many relationship between Phone and Peron entities and get rid of PersonPhone entity.

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

#3


To set-up the same mapping with Fluent NHibernate, do this:

要使用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");
    }
}

#1


The answer is to use the element in your composite key rather than the key-property

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

<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>

#2


I think It is more proper to consider Many-to-Many relationship between Phone and Peron entities and get rid of PersonPhone entity.

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

#3


To set-up the same mapping with Fluent NHibernate, do this:

要使用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");
    }
}