Table-per-concrete-class in NHibernate?
Normally when I have a problem I can't solve right away, I bang away at it until I have a half-assed solution that I can post here so that others can provide a better solution in the comments. It's how I've found about four methods for testing RedirectToAction, got tips for automating my deployments, and figured out the ConventionController. Quite frankly, I post here so that someone else can show me a better way to do things 'cause I've learned long ago my way ain't it.
This time, however, I've searched and experimented and have come up empty. So there will be no facade that I know what I'm doing this time. I'll just plain admit that I can't get it to work. I suppose I could bitch and complain about how hard this is. That seems to be a common theme I've seen in many other places when someone can't figure something out. Whine about how it should be easier, then have some kid in tenth grade post a simple yet elegant solution in the comments within the first five minutes. Alas, I don't have the pride to assume that it's someone else's fault I can't get my work done.
'Spose I should get to the problem at hand lest I lose potential problem-solvers.
I have a domain object called Job. It contains a collection of Location objects. A Location is an abstract class with two implementations: RuralLocation and UrbanLocation. The heart of my problem is: How do I represent this in an NHibernate mapping?
As defined in the documentation, I'm using a "table-per-concrete-class" strategy. I'll listen to arguments that it's not appropriate but consider this: Locations are value objects. They have no identity in and of themselves. A sample location would be NE-15-1-29-1W, which is a rural location (Northeast quarter section, section 15, township 1, range 29, 1 west of the prime meridian). There is no benefit to storing this as an individual entity in the database and attaching it to many jobs. Locations are essentially bandied around like money when you listen to the clients talk.
The reason I'm not considering a "table-per-class" or "table-per-subclass" hierarchy is because the two classes have exactly zero fields in common. So in the former, we'd have a table where half the fields would be null in every single row. And in the latter, we'd have a Location table containing two fields, an ID and a LocationType, and nothing else. Maybe having such a table isn't too bad but it sure feels like I'm altering the schema for the sake of NHibernate.
So for better or for worse, I have a "table-per-concrete-class". This is easy enough to represent in mapping files for each class individually as per the NHibernate documentation. Where I'm stuck is how to link these concrete classes back to the Job mapping file. Back when I had only the one location type, the mapping looked so:
<bag name="Locations" cascade="all-delete-orphan">
<key column="JobID" />
<one-to-many class="Trilogy.Gunton.Model.RuralLocation" />
Fairly straightforward and pretty much right out of the docs. But now, I need to map to an abstract Location class that has no representation in NHibernate. The docs mention the <any> element and Ayende has something similar but for the life of this hillbilly, the answer still eludes.
So to my insightful and, I pray, generous readers: <ahem>....help!
### UPDATE ###
Sorry folks, forgot to include relevant diagrams. Database diagram and class diagram are included below. The Locations property on Job is an IList<Location>. Click for larger versions:
Kyle the Unassisted