Fluent Nhibernate多对多关系/依赖关系层次结构



我正在尝试创建一个显示事件依赖关系的测试应用程序:即生成的依赖关系图(而不仅仅是树图)。类似于:

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

另一个要求是我能够在两个方向上遍历图:给定任何一个事件,我都可以使用Nhibernate访问它的依赖关系及其先决条件。

许多事件可以依赖于一个事件的发生。。。而且任何给定的事件都可以取决于许多其他事件。模型应该是什么样子(或者这需要多个模型)?如何使用Fluent NHibernate进行映射?是否有配置/映射可以防止循环引用?

我们做了类似的事情,它的映射方式是依赖事件应该有一个映射到父事件的列。这将创建映射有效所需的必要父/子关系,并防止某种循环引用。我们通过代码映射切换到了NH3.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();
        }
    }

这应该映射出您需要的链接表。您需要自己防范某种程度的"循环性"——也就是说,在您的业务逻辑中,确保您不能创建循环或某种大规模的对象图依赖性问题。

我最终得到的解决方案(到目前为止)。。。

模型中:

    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;
    }

这种方法有一些折衷:数据库是非规范化的,但我不必创建一个新的依赖对象,并为每个票证填充一个依赖/prereq票证列表,然后进行检查。现在用这种方式编码似乎更容易。欢迎提出建议!

相关内容

  • 没有找到相关文章

最新更新