2012-07-17 122 views
3

我有一个多对多的分层情况,我只是无法弄清楚如何解决明智的映射。流利的nhibernate多对多与以下多对多映射

我有一个实体事件。这个事件可以有很多事件。一个事件不过是一个价值对象,所以我创建了一个多对多的映射,它工作得很好。

现在到了位,我不能找出...选择一个事件的每一个事件可以有多种原因(这是一个值对象也一样)

下面是简单的数据模型(事件和原因都存储在SystemValues和具有类型作为其discriminatorvalue): enter image description here

(在表IncidentEvent ID是一个代理主键,以避免与复合键麻烦)

我的映射如下所示(简化): 事件:

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"); 
    } 
} 

事件(从一般的 'SystemValueMap' subclassmapped):

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"); 
    } 
} 

原因:

public class CauseMap : SubclassMap<Cause> { 
    public CauseMap() { DiscriminatorValue((int)SystemValue.Type.Cause); } 
} 

正如你所看到的 '事件' 的映射是一个烂摊子,当然还有它不起作用。当插入完成时,我得到了外键约束,因为NHibernate尝试将EventID插入到表IncidentEventCause的列IncidentEventID中。我可能需要告诉Nhibernate如何使用IncidentEventID。 我需要让事件知道它与事件的多对多关系,并且它与事件的关系如下,但我恐怕我不知道如何。

希望有人能指出我正确的方向。

回答

2

如果可能,您应该重构数据库模式并使用事件Id在表IncidentEventCause中交换IncidentEventId。

你想要的映射是不容易的。这里是一个解决方法,其中持久性泄漏到域中。

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); 
    } 
} 
+0

谢谢!我想我的思维方式真的陷入了困境。我根据您的建议重构了所有内容,现在所有功能都可以使用。 – scratchyback 2012-07-18 13:50:41

+0

很高兴我能帮上忙 – Firo 2012-07-18 17:59:17