2011-01-20 49 views
2

我们已经实施我们的领域模型使用问责模式,我们试图坚持使用NHibernate与流利的NHibernate定义地图。你如何将问责制模式映射到SQL与NHibernate

实际上,我们有3个实体Accountability(用于定义各方之间的关系),Party(用于定义方,即联系人,人员,业务等)和AccountabilityType(用于指定问责关系,即“属于“,”拥有者“等)

根据定义地图,我遇到了一堵砖墙。

的ERD看起来像这样(aaarrgg新用户不能发布图片,生活和它的小的挑战):

我从地图希望你能找出ERD。

的实体的定义如下(他们已经简单化了用于测试):

public class AccountabilityType 
{ 
    public virtual string Id { get; set; } 

    public override int GetHashCode() 
    { 
     return Id.GetHashCode(); 
    } 

    public override bool Equals(object obj) 
    { 
     var other = obj as AccountabilityType; 
     if (other == null) 
      return false; 
     return other.GetHashCode() == GetHashCode(); 
    } 
} 


public class Accountability 
{ 
    #region Properties 

    public virtual Guid Id { get; set; } 

    public virtual Party Parent { get; set; } 

    public virtual Party Child { get; set; } 

    public virtual AccountabilityType Type { get; set; } 

    #endregion 

    #region Methods 

    public override int GetHashCode() 
    { 
     return Type.GetHashCode()^Parent.GetHashCode()^Child.GetHashCode(); 
    } 

    public override bool Equals(object obj) 
    { 
     var other = obj as Accountability; 
     if (other == null) 
      return false; 
     return other.GetHashCode() == GetHashCode(); 
    } 

    #endregion 
} 

public class Party 
{ 
    public Party() 
    { 
     ParentAccountabilities = new List<Accountability>(); 
     ChildAccountabilities = new List<Accountability>(); 
    } 

    #region Properties 

    public virtual Guid Id { get; set; } 

    public virtual string Name { get; set; } 

    public virtual string Type { get; set; } 

    // Exposed for persistence, Hackity Hack, dont hate the player hate the game 
    public virtual IList<Accountability> ParentAccountabilities { get; set; } 

    // Exposed for persistence, Hackity Hack, dont hate the player hate the game 
    public virtual IList<Accountability> ChildAccountabilities { get; set; } 

    #endregion 

    #region Overrides 

    public override int GetHashCode() 
    { 
     return Type.GetHashCode()^Name.GetHashCode(); 
    } 

    public override bool Equals(object obj) 
    { 
     var other = obj as Party; 
     if (other == null) 
      return false; 
     return other.GetHashCode() == GetHashCode(); 
    } 

    #endregion 
} 

最后流利的地图如下:

public class AccountabilityTypeMap : ClassMap<AccountabilityType> 
{ 
    public AccountabilityTypeMap() 
    { 
     Id(p => p.Id).GeneratedBy.Assigned(); 
    } 
} 

public class AccountabilityMap : ClassMap<Accountability> 
{ 
    public AccountabilityMap() 
    { 
     Id(p => p.Id).GeneratedBy.Guid(); 

     References(p => p.Parent, "ParentId").Cascade.None(); 

     References(p => p.Child, "ChildId").Cascade.All(); 

     References(p => p.Type, "AccountabilityTypeId").Cascade.None(); 
    } 
} 

public class PartyMap : ClassMap<Party> 
{ 
    public PartyMap() 
    { 
     Id(p => p.Id).GeneratedBy.Assigned(); 

     Map(p => p.Name); 

     Map(p => p.Type); 

     HasManyToMany(p => p.ChildAccountabilities) 
      .Table("Accountability") 
      .ParentKeyColumn("ChildId") 
      .ChildKeyColumn("ParentId") 
      .Cascade.All(); 

     HasManyToMany(p => p.ParentAccountabilities) 
      .Table("Accountability") 
      .ParentKeyColumn("ParentId") 
      .ChildKeyColumn("ChildId") 
      .Cascade.None() 
      .Inverse(); 
    } 
} 

的实体持续到数据库,然而,NHibernate在session.Flush()上抛出一个错误,错误表明它试图插入一个带有空ID的Accountability实体。这首先是不可能的,因为Id是不可空的Guid,并且我已经通过对象模型来确保不存在具有空/空id的对象。

任何建议将最赞赏:)

感谢

回答

0

看来我感到困惑。我没有处理ManyToMany映射,因为我正在建模我的域中的桥表。映射应该看起来像这样。

public class AccountabilityTypeMap : ClassMap<AccountabilityType> 
{ 
    public AccountabilityTypeMap() 
    { 
     Id(p => p.Id).GeneratedBy.Assigned(); 
    } 
} 

public class AccountabilityMap : ClassMap<Accountability> 
{ 
    public AccountabilityMap() 
    { 
     Id(p => p.Id).GeneratedBy.Guid(); 

     References(p => p.Parent, "ParentId").Cascade.None(); 

     References(p => p.Child, "ChildId").Cascade.All(); 

     References(p => p.Type, "AccountabilityTypeId").Cascade.None(); 
    } 
} 

public class PartyMap : ClassMap<Party> 
{ 
    public PartyMap() 
    { 
     Id(p => p.Id).GeneratedBy.Guid(); 

     Map(p => p.Name); 

     Map(p => p.Type); 

     HasMany(p => p.ChildAccountabilities) 
      .KeyColumn("ParentId") 
      .Inverse() 
      .Cascade.All(); 

     HasMany(p => p.ParentAccountabilities) 
      .KeyColumn("ChildId") 
      .Inverse() 
      .Cascade.All(); 
    } 
} 
0

如果家长没有对孩子设置你可以得到一个空。当添加一个Child对象时,其父属性必须设置为父对象。

考虑:

var parent = new Party(); 
var child = new Accountability(); 
parent.ChildAccountabilities.Add(child); 

家长知道孩子,但孩子不知道父。尝试明确设置对孩子的父母:

var parent = new Party(); 
var child = new Accountability(); 
child.Parent = parent; 
parent.ChildAccountabilities.Add(child); 

如果解决了问题,那么它只是归结为您想如何在添加一个孩子封装设置Parent属性。 This blog entry可能会有所帮助。