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 に挿入しようとするため、foreignkey 制約が発生します。おそらく、代わりに IncidentEventID を使用する方法を Nhibernate に伝える必要があります。イベントに、インシデントとの多対多の関係と、原因との関係に従うことを認識させる必要がありますが、どうすればよいかわかりません。

誰かが私を正しい方向に向けることができることを願っています。

4

1 に答える 1

2

可能であれば、データベース スキーマをリファクタリングし、IncidentEventId をテーブル IncidentEventCause の 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 に答える