用流利的Nhibernate坚持一棵简单的树

时间:2013-10-13 12:43:52

标签: graph tree fluent-nhibernate composite fluent-nhibernate-mapping

我有一个树状结构模型(使用复合模式) 它的类图是这样的: composite class diagram

数据库图表: database diagram

树的样本: enter image description here

当我想坚持其深度超过一的CombatElement树时,问题就出现了,当我试图坚持这样的对象时,NHibernate只保存第一级的对象并忽略连接到第二级对象的对象所以:

如果我创建这个树:

 CombatElement fe = new Formation() { Name = "Alpha Company" };

        fe.Add(new Soldier()
        {
            Name = "Joe",
            Rank = 1
        });
        fe.Add(new Soldier()
        {
            Name = "Jack",
            Rank = 2
        });

        CombatElement platoon =
            new Formation();
        platoon.Name = "1st Platoon";
        fe.Add(platoon);
        platoon.Add(
            new Soldier()
            {
                Name = "Adam",
                Rank = 2

            });
        platoon.Add(
            new Soldier()
            {
                Name = "Arthur",
                Rank = 3

            });

只有“乔”,“第一排”和“杰克”将被保存到数据库中,第一排的子系统“亚瑟”和“亚当”将被忽略,不会被保存!!

这里是映射类:

public class CombatElementMap:ClassMap<CombatElement>
{
    public CombatElementMap()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Name).Not.Nullable().Length(100);
    }

}

///////////////////////////

public class FormationMap:ClassMap<Formation>
{
    public FormationMap()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();
        HasMany(x => x.Elements).Cascade.AllDeleteOrphan();
    }
}

///////////////////////////

 public class SoldierMap:ClassMap<Soldier>
{
    public SoldierMap()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Rank);
    }
}

我已将级联对象级联,但问题仍然存在。 为什么会这样?这让我很困惑!!

1 个答案:

答案 0 :(得分:1)

你在类结构中使用继承,正确地指导nHibernate存储基类和子类属性,你必须重新定义你的映射,也许还有一些对象

基本上,您应该对所有子类使用SubClassMap而不是ClassMap,并且只在这些子类映射中定义新属性。

我为元素添加了一些代码(根据你的图表进行最佳猜测)

public abstract class CombatElement
{
    public CombatElement()
    {
        Elements = new List<CombatElement>();
    }

    public virtual Guid Id { get; set; }

    public virtual string Name { get; set; }

    public virtual IList<CombatElement> Elements { get; set; }

    public virtual void Add(CombatElement element)
    {
        Elements.Add(element);
    }
}

public class Formation : CombatElement
{
}

public class Soldier : CombatElement
{
    public virtual int Rank { get; set; }
}

新映射看起来像这样:

public class CombatElementMap : ClassMap<CombatElement>
{
    public CombatElementMap()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Name).Not.Nullable().Length(100);
        HasMany(x => x.Elements)
            .AsBag()
            .Fetch.Join()
            .Cascade.AllDeleteOrphan();
    }

}

public class FormationMap : SubclassMap<Formation>
{
    public FormationMap()
    {
        //Id(x => x.Id).GeneratedBy.GuidComb();
    }
}

public class SoldierMap : SubclassMap<Soldier>
{
    public SoldierMap()
    {
        //Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Rank);
    }
}

还要确保在保存实体后调用.Flush,否则它可能不会存储在您的数据库中。

session.Save(fe);
session.Flush();