2012-03-05 118 views
0

我想創建一個測試應用程序,顯示事件依賴關係:即結果依賴關係圖(而不僅僅是一個樹形圖)。喜歡的東西:流利Nhibernate多對多的關係/層次的依賴關係

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

另一個要求是,我能夠穿越在兩個方向上圖:給定任何一個事件,我可以使用NHibernate訪問它的依賴以及它的先決條件。

許多事件可能依賴於一個事件發生......但任何給定的事件也可能依賴於許多其他事件。 模型應該是什麼樣子(或者這是否需要多個模型)?如何使用Fluent NHibernate映射它?是否有配置/映射可以防止循環引用?

回答

0

我們做了類似的事情,它的映射方式是依賴事件應該有一個映射到父事件的列。這將創建必要的父/子關係,使映射成爲有效的並防止某種循環引用。我們通過代碼映射切換到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 2012-03-05 17:36:55

+0

我有一個FluentConfigurationException抱怨重複的Event_id。在.AsBag()之前添加了.ChildKeyColumn(「TheEvent」)。將保持你張貼如何可行的結果。 – Handprint 2012-03-05 18:52:56

+0

是的 - 根據您的ID設置,您可能需要覆蓋一些列的默認設置。 – Fourth 2012-03-05 21:33:15

0

我結束了(到目前爲止)的解決方案......

在Model:

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

我阻止圓形裁判的看對於虛假來源:

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是非規格化的,但我不必創建新的依賴項對象並填充每張票據的依賴/ prereq票據列表,然後執行我的檢查。目前看起來似乎更容易編碼。開放給建議,但!