NHibernate映射 - 自引用:父和子

时间:2014-07-02 07:50:17

标签: nhibernate tree self bag

我正试图拥有这种模型:

public class Activity
{
    public virtual int ID { get; set; }

    public virtual int? ParentID { get; set; }
    public virtual int? RootID { get; set; }

    public virtual Activity Parent { get; set; }
    public virtual Activity Root { get; set; }
    public virtual IList<Activity> Children { get; set; }
}

如果从结构的角度来看它,它就是一棵树。 根元素没有父元素或根,但可能有子元素。 它的任何子节点都必须有父节点和根节点(对于第一级子节点root = parent)

映射器是这样的:

public class ActivityMap : ClassMapping<Activity>
{
    public ActivityMap()
    {
        Table("activity");
        Lazy(true);
        Id(x => x.ID, map => map.Generator(Generators.Identity));

        ManyToOne(x => x.Root, map => { map.Column("RootID"); map.Cascade(Cascade.All); });

        Bag(x => x.Children,
           mapping =>
           {
               mapping.Inverse(false);
               mapping.Lazy(CollectionLazy.Lazy);
               mapping.Key(k => k.Column("ParentID"));
               mapping.Cascade(Cascade.All);
           },
           mapping => mapping.ManyToMany(map=>map.Class(typeof(Activity)))
           );
    }
}

问题是当我尝试获取子进程时,sql语句如下所示:

SELECT children0_.ParentID as ParentID1_,
children0_.elt as elt1_, 
activity1_.ID as ID55_0_, 
activity1_.TaskID as TaskID55_0_, 
activity1_.ActivityTypeID as Activity3_55_0_, 
activity1_.StateID as StateID55_0_, 
activity1_.Continueforward as Continue5_55_0_, 
activity1_.Ordernumber as Ordernum6_55_0_, 
activity1_.IsDeleted as IsDeleted55_0_, 
activity1_.Created as Created55_0_, 
activity1_.Modified as Modified55_0_, 
activity1_.StartTime as StartTime55_0_, 
activity1_.EndTime as EndTime55_0_, 
activity1_.Progress as Progress55_0_, 
activity1_.RootID as RootID55_0_ 
FROM Children children0_ left outer join activity activity1_ on children0_.elt=activity1_.ID WHERE children0_.ParentID=?
  1. 首先,它似乎正在寻找不存在的Children表。应该是活动表
  2. 第二:我不确定那条“elt”栏是什么......它不存在于任何地方
  3. 任何人都知道如何进行此映射?

    稍后编辑: 在回答第二个问题时发现: NHibernate elt field

1 个答案:

答案 0 :(得分:0)

在我后来的编辑中,我得到了第二个问题的答案。

对于第二个问题,我发现的解决方案是放弃与Root实体的关系

ManyToOne(x => x.Root, map => { map.Column("RootID"); map.Cascade(Cascade.All); });

并将其替换为

Property(x => x.RootID);

因为我没有必要为Root提供整个实体。 我也改变了这样的儿童包:

Bag(x => x.Children,
           mapping =>
           {
               mapping.Inverse(false);
               mapping.Lazy(CollectionLazy.Lazy);
               mapping.Key(k => k.Column("ParentID"));
               mapping.Cascade(Cascade.All);
           },
           mapping => mapping.OneToMany()
           );