3

我有一个多对多的分层情况,我只是不知道如何明智地解决映射问题。

我有一个实体事件。这个事件可以有很多事件。一个事件只不过是一个值对象,所以我创建了一个运行良好的多对多映射。

现在是我无法弄清楚的一点......为事件选择的每个事件都可以有多个原因(这也是一个值对象)

下面是简化的数据模型(事件和原因都存储在 SystemValues 中,并以 Type 作为它们的鉴别值): 在此处输入图像描述

(表 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”映射的子类):

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。我需要让事件意识到它与事件的多对多关系以及它与原因的跟随关系,但恐怕我不知道如何。

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

4

1 回答 1

2

如果可能,您应该重构数据库架构并在 IncidentEventCause 表中将 IncidentEventId 与 EventId 交换。

您想要的映射并不容易。这是持久性泄漏到域中的解决方法。

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);
    }
}
于 2012-07-18T12:29:55.647 回答