R – NHibernate join table mappings

collectionsjoin;nhibernate

I have an interesting issue, which I can't seem to find a satisfying answer for. It concerns join tables.

Basically (I'm sure this has been out here in some form or another, but I cant find it) I have 3 tables. A Person table, Address table, PersonAddress..

Person

PersonID
Name
Age
etc..

Address

AddressID
AddressLine1
AddressLine2
City
State
Zip

PersonAddress

AddressID
PersonID
AddressType

The reason why AddressType is on the join table is simply because these addresses can be shared amongst people throughout the company, as a Shipping type, Physical Location, or Billing.

Is there even possibly away to join these as a collection or something

I would like to manage something like this

Address Class

AddressLine1
AddressLine2
City
State
Zip
AddressType

Person Class

Name
Age
IListAddresses

This person would hold a collection of addresses for himself.

If anyone has a way that I could accomplish this in Fluent or just straight XML mapping, that would be terrific. I just feel this should be something easy, but I am missing it. And not having the correct termonology (bridge table, join table, collection table, join-parts table) I cant seem to google to save my life.

Thanks in advance to any help!

Best Answer

I think this can be achieved pretty easily if I understand correctly. :) You have a Person object and you want it to contain some properties and a collection of person's addresses that can also be shared amongst other users, right? Well, to set this up using Fluent NHibernate I would do something like this:

// Person Entity
public class Person
{
    public int Id { get; private set; }
    public string Name { get; set; }
    public IList<PersonAddress> Addresses { get; set; }
}

// Fluent Mapping
public class PersonMap : ClassMap<Person>
{
    public PersonMap() {
        Id(x => x.Id);
        Map(x => x.Name);
        HasMany(x => x.Addresses).Cascade.All();
    }
}

// Address Entity
public class Address
{
    public int Id { get; private set; }
    public string Address1 { get; set; }
    public string City { get; set; }
    public IList<PersonAddress> People { get; set; }
}

// Fluent Mapping
public class AddressMap : ClassMap<Address>
{
    public AddressMap() {
        Id(x => x.Id);
        Map(x => x.Address1);
        Map(x => x.City);
        HasMany(x => x.People).Cascade.All();
    }
}

// PersonAddress Entity
public class PersonAddress
{
    public int Id { get; private set; }
    public Person Person { get; set; }
    public Address Address { get; set; }
    public AddressType Type { get; set; }
}

// Fluent Mapping
public class PersonAddressMap : ClassMap<PersonAddress>
{
    public PersonAddressMap() {
        Id(x => x.Id);
        References(x => x.Person);
        References(x => x.Address);
        Map(x => x.Type).CustomTypeIs(typeof(AddressType));
    }
}

Basically, this allows a Person to have a collection of Addresses and those Addresses can be shared amongst the company (multiple persons). You almost have a many-to-many setup but because you storing state info in the PersonAddress it became two one-to-many relationships in the Person and Address Entity.

Sorry if I gave you more than you wanted! Just felt like typing! :p

Let me know if this helps or if you have any questions or if I'm totally off base.