0

我有一个树结构模型(使用复合模式)。
它的类图是这样的: composite class diagram坚持一个简单的树与流利Nhibernate

数据库图:树的 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 

      }); 

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

这里是映射类:

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对象,但问题仍然存在。 为什么会发生这种情况?它只是让我困惑!

回答

1

您使用继承你的类结构,适当instrcut 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(); 
+0

你是我的救星,我已经投入了大量的时间来解决这个问题,但没有达到任何一点。 SqlServer中的数据库图也发生了变化。非常感谢。 –

+0

@HashemAboonajmi欢迎;) – MichaC

+0

我也试图用AutoMapping解决这个问题。 AutoMapper将GetEumerator()方法视为一个实体,并且对此方法的投诉没有Id映射!这里是一个问题的链接:http://stackoverflow.com/questions/19189185/automapping-a-composite-model-with-composite-iteration-with-fluentnhibernate如果你能帮助我解决这个问题,我将不胜感激。 –