tags:

views:

246

answers:

1

I'm having an issue mapping what I would think is a fairly simple association.

Here's an example of the domain model I'm trying to map:

public class MyClass
{
    IDictionary<string, DateTime> Dates { get; set; }
}


public class MyOtherClass
{
    IDictionary<string, DateTime> Dates { get; set; }
}

I'd like the Dates property to be mapped into a single table, something like this:

TABLE Dates
COLUMNS
    ParentId    (Parent class key value)
    ParentType  (Parent class type)
    DateType    (Index value for dictionary)
    DateValue
SAMPLE
ParentId        ParentType  DateType    DateValue
----------------------------------------------------------
1               MyClass             TYPEA       2009-10-09
1               MyOtherClass        TYPEA       2009-11-08

I'm open to suggestions as to how to better model this, but basically I want a one to many association without littering the database with a separate table for every collection.

I'm using DateTime in this particular example as that's what I'm trying to do right now, but it could just as easily be any type, even another custom class that I would want to model in the same way.

Any idea as to how this should be mapped?

I believe this is similar to a question I had asked previously (http://stackoverflow.com/questions/722550/nhibernate-how-do-i-map-mutiple-parents-children-of-a-common-type-into-a-single) but that solution ended up in crosstables all over the place which isn't really the result I'm trying to achieve.

A: 

Discrimination must be between MyClass and MyOtherClass, not in the Dates table. You need a database structure like this:

Table Classes (for MyClass/MyOtherClass):
    ClassID (unique primary key)
    ClassType
    ...

Table Dates:
    ClassID (foreign key from above)
    Date (value)

Now, you need an abstract base class MyBaseClass from which MyClass and MyOtherClass derive, and your mapping would then be something like this (pseudo-code, don't expect it to be entirely correct):

<class="MyBaseClass", abstract="true", table="Classes">
  <id .../>
  <set name="Dates"... />
  <discriminator column="ClassType"/>
  <subclass type="MyNamespace.MyClass, MyAssembly" discriminator-value="'MyClass'">
    ...
  </subclass>
  <subclass type="MyNamespace.MyOtherClass, MyAssembly" discriminator-value="'MyOtherClass'">
    ...
  </subclass>
</class>

HTH!

Thomas Weller
This still relies on a common base class which I don't have nor does it really fit to create one.
Chris Stavropoulos
There simply is no other way, if you want to have both classes in one table... And what's wrong with a base class, it feel like the natural fit in your case anyway ?!
Thomas Weller
If you thing the items belong in the same table, then it fits that they have a common base relationship.
Aaron Fischer
So in a situation where two classes are completely unrelated with no base class but coincidentally implement the exact same IDictionary<string, DateTime> Dates property, the best practice would be to have those actually stored in two separate tables?
Chris Stavropoulos
Sure. Why would you want to have two completely unrelated classes - which also means that the refered dates are completely unrelated! - relating to one and the same table. This would be a certain recipe for a big ball of mud. The dates are only coincidentally of the same format, but they have nothing to do with each other, so they _must_ go in separate tables in this case.
Thomas Weller
Alright, I'll agree with you. Apparently I've got my wires crossed and I'm focusing too intently on keeping the database clean based on the data itself rather than focusing on the domain model.I do have things working with the base class for the moment using a joined-subclass methodology.Thanks for the assistance!
Chris Stavropoulos