我有一个树状结构模型(使用复合模式) 它的类图是这样的:
数据库图表:
树的样本:
当我想坚持其深度超过一的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);
}
}
我已将级联对象级联,但问题仍然存在。 为什么会这样?这让我很困惑!!
答案 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();