2011-01-20 27 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可能會有所幫助。