views:

393

answers:

2

I've got two theoretical domain objects:

public class Person { public virtual int Id { get; private set; } }

public class PersonMap : ClassMap<Person>
{
 public PersonMap() { Id( x => x.Id ); }
}

public class DriversLicense
{
 public virtual Person Person { get; set; }
 public virtual string State { get; set; }
}

public class DriversLicenseMap : ClassMap<DriversLicense>
{
 public DriversLicenseMap()
 {
  References( x => x.Person );
  Map( x => x.State );
 }
}

Where the Person object is to be used as the PK on DriversLicense. I don't want the Person object to have any knowledge of DriversLicense so the relationship is maintained strictly in the DriversLicense class. There is exactly one DriversLicense per person.

When setup this way I'm getting the following exception:

System.Xml.Schema.XmlSchemaValidationException: The element 'class' in namespace 'urn:nhibernate-mapping-2.2' has invalid child element 'property' in namespace 'urn:nhibernate-mapping-2.2'. List of possible elements expected: 'meta, jcs-cache, cache, id, composite-id' in namespace 'urn:nhibernate-mapping-2.2'.

Adding an Id property to the DriversLicense type fixes the problem.

Is there a way to use the Person itself as the primary key in the DriversLicense table so that the underlying table just uses the Person.Id for it's primary key?

+1  A: 

@Matthieu got me on the right track with composite keys. I had to use the UseCompositeId() method and then override Equals & GetHashCode for the Drivers License object.

Here's how it looks in fluent NHibernate:

public class DriversLicense
{
        public virtual Person Person { get; set; }
        public virtual string State { get; set; }

        public override bool Equals( object obj )
        {
            if( ReferenceEquals( obj, null ) ) return false;

            // Cast, instead of 'as' throws runtime exception when obj is not an 
            // DriversLicense.
            var comp = (DriversLicense) obj;

            if( Person == null || comp.Person == null )
                return false;

            return Person.Equals( comp.Person );
        }

        public override int GetHashCode() 
        {
   return Account == null ? -1 : Account.GetHashCode(); 
  }
}

public class DriversLicenseMap : ClassMap<DriversLicense>
{
        public DriversLicenseMap()
        {
                UseCompositeId().WithKeyReference( x => x.Person );
                Map( x => x.State );
        }
}
Paul Alexander