2012-03-05 119 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票据列表,然后执行我的检查。目前看起来似乎更容易编码。开放给建议,但!