0

Recently I've found an example on NHibernate's one-to-many relationship. The mapping goes like this:

<class name="Company" table="Company">
    <id name="Id" type="Int32" unsaved-value="0">
      <generator class="identity"/>
    </id>
    <version name="Version"/>
    <property name="Name"/>
    <set name="Customers" inverse="true" lazy="true" >
      <key column="Id"/>
      <one-to-many class="Customer"/>
    </set> 
</class>

<class name="Customer" table="Customer">
    <id name="Id" type="Int32" unsaved-value="0">
      <generator class="identity"/>
    </id>
    <version name="Version"/>
    <property name="DateOfBirth"/>
    <property name="FirstName"/>
    <property name="Surname"/>
    <many-to-one name="Company" column="CompanyId" cascade="all-delete-orphan"/>
</class>

And this are the classes:

public class Company
{
    private ISet<Customer> customers = new HashedSet<Customer>();
    public int Id { get; set; } 
    public string Name { get; set; }
    public int Version { get; set; }
    public ISet<Customer> Customers
    {
        get { return customers; }
        set { customers = value; }
    }
}

public class Customer
{
    public Company Company { get; set; }
    public DateTime? DateOfBirth { get; set; }
    public string FirstName {get;set;}
    public int Id { get; set; }
    public string Surname {get;set;}
    public int Version { get; set; }
}

What I don't like about this code is the inclusion of the parent inside the child, the whole Company object inside the Customer one. Won't this be a circular reference. I mean, when this graph loads won't I be able to do something like currentCustomer.Company.Customers.First().Company.Customers.Last() ... and so on? Or it doesn't work like that?

Assuming the underlying table Customer had only a string column CompanyName, how could I map that? How would be the mapping if instead of a public Company Company I'd have a public string CompanyName in the Customer class?

CMPerez
  • 905
  • 1
  • 10
  • 25

1 Answers1

5

yes you can write:

currentCustomer.Company.Customers.First().Company.Customers.Last() 

as many time you want inside an open session, this will issue a query for loading the company, then (probably one) for fetching the Customers collection, and then all will happen in memory. There is nothing so strange about it, apart the fact that probably is not so useful. If you just have a company name, yes you can map it as a simple property of type string.

Felice Pollano
  • 32,832
  • 9
  • 75
  • 115
  • +1 there's nothing strange about it. If you write that code what else are you expecting it to do? The company is the customer's company, the first customer in that company is also the customer, and so on. – Henry Mar 16 '12 at 10:48