2012-03-05 10 views
0

イベントの依存関係を示すテストアプリケーションを作成しようとしています。つまり、ツリーグラフとは対照的に結果として生じる依存グラフです。以下のようなもの:Fluent Nhibernate多対多リレーションシップ/依存関係の階層

public class Event() { 
    public virtual int Id {get;set;} 
    public virtual IList<Event> Dependencies {get;set;} 
} 

他の要件は、私は両方の方向にグラフをトラバースすることができるということである。いずれかのイベントを考えると、私はNHibernateはを使用して、依存関係、並びにその前提条件にアクセスすることができます。

多くのイベントは、発生している1つのイベントに依存する可能性がありますが、特定のイベントも他の多くのイベントに依存する可能性があります。 モデルはどのように見えるべきですか(または複数のモデルが必要ですか)? Fluent NHibernateを使ってどのようにマッピングすることができますか?そして、循環参照から保護するための設定/マッピングはありますか?

答えて

0

私たちはこれに似たようなことをします。従属イベントには、親イベントに対応する列が必要です。これは、マッピングが有効で何らかの循環参照を防止するために必要な親子関係を作成します。我々はので、私の流暢は少し手抜きが、HERESに私の最高の推測があるかもしれない、コードマッピングによりNH 3.2に切り替え:

public class EventMap : ClassMap<Event> 
{ 
    public EventMap() 
    { 
     //the normal ID and property stuff 

     References(x => x.ParentEvent).Column("ParentEventId"); 

     HasMany(x => x.Dependencies).KeyColumn("ParentEventId"); 
    } 
} 

編集:

申し訳ありません - あなたはHasManyToManyを望んで表示されませんでした。それは次のようになります。

public class EventMap : ClassMap<Event> 
    { 
     public EventMap() 
     { 
      //the normal ID and property stuff 

      HasManyToMany(x => x.Dependencies).Table("EventDependentEvent").AsBag(); 
     } 
    } 

これは、必要なリンクテーブルをマップする必要があります。ある程度の "循環性"を守る必要があります。つまり、ビジネスロジックでループや大量のオブジェクトグラフの依存関係の問題を作成できないことを確認してください。

+0

すぐにこれを試してみましょう...今すぐ他の火事があります。 ;) – Handprint

+0

重複するEvent_idについて不平を言うFluentConfigurationExceptionがあります。 .AsBag()の直前に.ChildKeyColumn( "TheEvent")を追加しました。あなたはどのように実行可能であるかが分かります。 – Handprint

+0

はい - IDの設定によっては、列のデフォルトの一部を無効にする必要があります。 – Fourth

0

私は(今のところ)になってしまったソリューション...モデルで

public virtual IList<Event> Dependencies{ get; set; } 
    public virtual IList<Event> Prerequisites{ get; set; } 

マッピングで:

 HasManyToMany(x => x.Dependencies) 
      .Table("Dependencies") 
      .ChildKeyColumn("Dependent"); 
     HasManyToMany(x => x.Prerequisites) 
      .Table("Prerequisites") 
      .ChildKeyColumn("Prerequisite"); 

そして私は見ることにより、円形のrefのを防ぎます偽の場合:

private bool IsPrerequisiteEvent(Event dependent, Event prereq) 
    { 
     bool isPrereq = false; 
     if (prereq == null) 
      isPrereq = false; 
     else if (dependent.Id == prereq.Id) 
      isPrereq = true; 
     else 
     { 
      int i = 0; 
      while (!isPrereq && i < dependent.PrerequisiteEvents.Count) 
      { 
       isPrereq |= IsPrerequisiteEvent(dependent.PrerequisiteEvents[i], prereq); 
       i++; 
      } 
     } 
     return isPrereq; 
    } 

    private bool IsDependentEvent(Event prereq, Event dependent) 
    { 
     bool isDependent = false; 
     if (prereq == null) 
      isDependent = false; 
     else if (dependent.Id == prereq.Id) 
      isDependent = true; 
     else 
     { 
      int i = 0; 
      while (!isDependent && i < dependent.DependentEvents.Count) 
      { 
       isDependent |= IsDependentEvent(prereq, dependent.DependentEvents[i]); 
       i++; 
      } 
     } 
     return isDependent; 
    } 

このアプローチにはトレードオフがあります:db ISは非正規化されていますが、新しい依存オブジェクトを作成して、各チケットの従属/前提条件チケットのリストに値を設定してからチェックを行う必要はありません。今のところこの方法を簡単にコーディングすることができます。しかし、提案にオープン!

関連する問題