0

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

数据库图: 数据库图

和树样本: 在此处输入图像描述

当我想保留其深度大于一的 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

            });

只有“Joe”、“1st Platoon”和“Jack”会被保存到数据库中,而“Arthur”和“Adam”作为 1st Platoon 的子元素将被忽略,不会被保存!!

这是映射类:

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

我已经级联了 Formation 对象,但问题仍然存在。为什么会这样?它只是让我感到困惑!

4

1 回答 1

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();
于 2013-10-13T13:52:09.663 回答