简体   繁体   中英

Class design and NHibernate mapping question

I have an Address class that I want to use for other objects address info. Below I paste 2 example classes Company and Person that use Address class

public class Company
{
    public virtual string Name { get; set; }
    public virtual string Phone { get; set; }
    public virtual string Fax { get; set; }

    public virtual Address Address { get; set; }
}

public class Person
{
    public virtual string Name { get; set; }
    public virtual string Phone { get; set; }
    public virtual string Fax { get; set; }

    public virtual Address Address { get; set; }
}

public class Address
{
    public virtual string Address1 { get; set; }
    public virtual string CityName { get; set; }
    public virtual string StateName { get; set; }
    public virtual string CountryName { get; set; }

    public virtual AddressOf AddressOf { get; set; }
    public virtual object Owner { get; set; }
}

public enum AddressOf : byte
{
        Company,
    Person
}

My plan is to have an addresses table that I will keep addresses of companies customers etc. Each address will have its unique id and will associate to the owner of the address via another owner_id and owner_type columns.

The way I normally did was I would have address columns on all tables that needed address information(then I could do component mapping for nhibernate) but now I'm thinking that may not be necessary and I can collect all addresses on one common table..

Now my challenge is how I map these to nhibernate. I thought of one-to-one mapping but could not figure how I will map owner_id column which should be foreignly generated from the owner / company, person etc.

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" >
    <class name="Company" table="Companiess">
        <id name="ID" column="ID" type="Int32" unsaved-value="0">
            <generator class="native" />
        </id>

        <property name="Name" />
        <property name="Phone" />
        <property name="Fax" />

        <one-to-one name="Address" class="Address"  />

    </class>
</hibernate-mapping>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="Addresses" table="Addresses   ">
        <id name="ID" column="ID" type="Int32" unsaved-value="0">
            <generator class="native" />
        </id>


        <property name="Address1" />
        <property name="CityName" />
        <property name="StateName" />
        <property name="CountryName" />

        <one-to-one "here is where im having trouble, I need to map owners id to owner_id column of Addresses table" ></one-to-one>


    </class>
</hibernate-mapping>

If you are seeing an architectural problem please also let me know as I have not used a separate address table this way before and I'm not yet entirely comfortable about it. Thanks!

You need the Company and Person classes to implement a common interface. Add a field in Address that will track if the row belongs to a Company or a Person. Then use the <any> tag in the Address mapping. See Ayende's post 'NHibernate Mapping - <any/>' on the subject.

I'm not sure why you want the bi-directional link from Address to the owner; would that really be necessary? Does an address really have to know who it is owned by?

You might want to consider dropping that relation and come up with a generic 'shared' relation class, like this:

public class Relation
{
  public virtual string Name { get; set; }
  public virtual string Phone { get; set; 
  public virtual string Fax { get; set; }
  public virtual Address Address { get; set; }
}

and...

public class Person : Relation
{
}
public class Company : Relation
{
}

And the mapping file:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" >
    <class name="Relation" table="Relations">
        <id name="ID" column="ID" type="Int32" unsaved-value="0">
            <generator class="native" />
        </id>

        <property name="Name" />
        <property name="Phone" />
        <property name="Fax" />
        <Component name="Address" class="Address" >
        ... address fields...
        </Component>

        <joined subclass="Person..." />

        <joined subclass="Company..." />


    </class>
</hibernate-mapping>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM