Reputation: 127
I have a many-to-many hierarchical situation I just can't figure out how to solve mapping wise.
I have an entity Incident. This Incident can have many Events. An event is nothing but a value object so i created a many-to-many mapping which works perfectly fine.
Now comes the bit i cant figure out... Every Event selected for an Incident can have multiple Causes (which is a value object as well)
Below is the simplified datamodel (events and causes are both stored in SystemValues and have Type as their discriminatorvalue):
(ID in table IncidentEvent is a surrogate primary key to avoid hassle with a composite key)
My mapping is as follows (simplified): Incident:
public class IncidentMap : ClassMap<Incident> {
public IncidentMap() {
Table("Incident");
Id(x => x.ID).GeneratedBy.Identity();
HasManyToMany(x => x.Event)
.Table("IncidentEvent")
.ParentKeyColumn("IncidentID")
.ChildKeyColumn("EventID");
}
}
Event (subclassmapped from a general 'SystemValueMap'):
public class EventMap : SubclassMap<StoryWhere> {
public EventMap() {
DiscriminatorValue((int)SystemValue.Type.Event);
HasManyToMany(x => x.Incident)
.Table("IncidentEvent")
.ParentKeyColumn("IncidentID")
.ChildKeyColumn("EventID");
HasManyToMany(x => x.Cause)
.Table("IncidentEventCause")
.ParentKeyColumn("IncidentEventID")
.ChildKeyColumn("CauseID");
}
}
Cause:
public class CauseMap : SubclassMap<Cause> {
public CauseMap() { DiscriminatorValue((int)SystemValue.Type.Cause); }
}
As you can see the mapping for 'Event' is a mess and of course it doesnt work. When an insert is done, I get foreignkey contraints as NHibernate tries to insert EventID into columns IncidentEventID of table IncidentEventCause. I probably need to tell Nhibernate how to use IncidentEventID instead. I need to make the Event be aware of it's many-to-many relation with incident and of it's following relation with Cause, but I'm afraid I don't know how.
Hoping someone can point me in the right direction.
Upvotes: 3
Views: 1593
Reputation: 30803
if possible you should refactor the database schema and exchange IncidentEventId with EventId in the table IncidentEventCause.
The mapping you want is not easily possible. Here a workaround where the persistence leaks into the domain.
public class IncidentMap : ClassMap<Incident>
{
public IncidentMap()
{
Id(x => x.ID).GeneratedBy.Identity();
HasManyToMany(x => x.Events)
.Table("IncidentEvent")
.ParentKeyColumn("IncidentID")
.ChildKeyColumn("EventID")
.ChildWhere("type=" + (int)SystemValue.Type.Event);
}
}
public class Event
{
private EventDetails Details { get; set; }
public string Name { get { return Details.Name; } set { Details.Name = value; } }
}
class EventDetails : SystemValue
{
public virtual string Name { get; set; }
}
public class EventMap : ClassMap<Event>
{
public EventMap()
{
Table("IncidentEvent");
Id(x => x.Id, "Id").GeneratedBy.Identity();
References(x => x.Incident, "IncidentID");
References(Reveal.Member<Event>("Details"), "EventID").Not.LazyLoad();
HasManyToMany(x => x.Causes)
.Table("IncidentEventCause")
.ParentKeyColumn("IncidentEventID")
.ChildKeyColumn("CauseID");
}
}
public class EventDetailsMap : SubclassMap<EventDetails>
{
public EventDetailsMap()
{
DiscriminatorValue((int)SystemValue.Type.Event);
Map(x => x.Name);
}
}
public class CauseMap : SubclassMap<Cause>
{
public CauseMap()
{
DiscriminatorValue((int)SystemValue.Type.Cause);
Map(x => x.Name);
}
}
Upvotes: 2