views:

332

answers:

3

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!

+1  A: 

Hi Matt,

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.

CalebHC
+1  A: 

I would move AddressType off PersonAddress table and put it on the Address Table. Then you should be able to map a regular Many-to-Many mapping.

public class PersonMap : ClassMap<Person>  
{  
public PersonMap()  
  {  
    Id(x => x.PersonId);  
    Map(x => x.Name);  
    HasManyToMany(x => x.Addresses)  
     .Cascade.All()  
     .WithTableName("PersonAddress");  
  }  
}
dionysus55
+1  A: 

Thank you Caleb for your response. You are not off base by any means, because this is currently how we have it set up. I was just hoping there was a way that I could possibly eliminate the two one-to-manys, but like you said, because we're storing the state info of the address type, it doesn't seem to allow for it.

I will keep this up here hoping that someone figures out a way to pull two entities out of this without having the need for the bridge class, but until then I am sure we will keep it how we have it, pretty much how you had stated Caleb.

Thanks!

Matt Braunwart