views:

1708

answers:

2

I am trying to get a collection of objects into a parent object through mapping.

I have a parent object "ScoreCard" whose primary key is a guid (Id) and a child "Score" object whose primary key is a guid (Id). I want to select the child objects for the parent based on two fields that both objects have but I can't get it to work, here's the mapping

<bag name="ScoreCard">
  <key>
    <column name="HoleId"/>
    <column name="PlayerId"/>
  </key>
  <one-to-many class="Score" not-found="ignore"/>
</bag>

I didn't design the database but the ScoreCard object comes from a view that returns both column I need plus the evil guid. Whatever I've tried, NHibernate keeps throwing an exception about the foreign key not being the same as the primary key.

This seems to me to be the most simple requirement, get a collection of things given some criteria, why am I so stuck?

Thanks for your help, sorry for the bad example code (subliminal golf watching at relatives house).

+1  A: 

The problem is this: NHibernate works best (but not only) for DDD, this means for creating domain classes first and make the database best fitting the domain model.

You have a composite-id relation to non-primary-key fields. So start praying that NHibernate can cope with that. Both composite-ids and relations by non-primary-keys are supported - for legacy databases - and generally discouraged for DDD.

I think the combination of both does not work. See this issue on NHibernates issue tracker: http://nhjira.koah.net/browse/NH-1722. You can vote for the feature there.

Stefan Steinegger
Thanks, I've got an example working with a composite key to a composite foreign key, but I can see that it is property ref that I need. It seems so tough that the ORM dictates the design of the database, but I can see your point regarding DDD, so I might consider a redesign while I still have chance.
Mark Dickinson
NHibernate tries to dictate as less as possible to the domain model, and does this pretty well (at least better than any alternative). By supporting every kind of relational model, it probably only covers around 90%. Linking rows by any column value is rare and hard to map to class models. Relational models are just much more flexible.
Stefan Steinegger
BTW: please accept my answer as the correct, if you think it is.
Stefan Steinegger
Yeah, I'm used to using procs to get data into objects so I can easily join to another table on whatever column I want. I understand that this is not the same as creating relationships between tables, so I'll change the database. Seeing how this plays out, I don't feel so bad now, and it gives me better design going forward.
Mark Dickinson
A: 

Well, I found it eventually. The parent object is drawn from a view giving three columns and no key. I can map a composite key to the HoleId and PlayerId instead of the evil guid that I found when I looked at the code. This is great as I can easily map the Score objects I need and then lazy load them using NHibernateUtil.Initialize.

My mapping xml needs to look like this

<class name="ParentObject">
    <composite-id>
      <key-property name="HoleId" column="HoleId" />
      <key-property name="PlayerId" column="PlayerId" />      
    </composite-id>
    <property name="EvilGuid" column="Id" />
    <bag name="ScoreCard">
      <key>
        <column name="HoleId"/>
       <column name="PlayerId"/>
      </key>  
      <one-to-many class="Score" not-found="ignore"/>
    </bag>
</class>

I got my inspiration from this post, please also pay attention to Stefan's answer as I feel I had a lucky break here, and the design could be made better with more thought about DDD.

Thanks for your help.

Mark Dickinson