2010-11-07 193 views
1

我是Fluent和NHibernate的新手,我不確定如何映射數據庫中存在的這種特定關係。我有下面的ER圖,概述了我的表結構。Fluent Nhibernate HasMany映射問題

ER Diagram

下面是我當前的C#實體類:

public class GroupHeader 
{ 
    public virtual Guid Id { get; private set;} 
    public virtual string Name { get; set; } 
    public virtual string Description { get; set; } 
    public virtual IList<RightHeader> Rights { get; set; } 
    public virtual IList<GroupRight> GroupRights { get; set; } 
    public GroupHeader() 
    { 
     GroupRights = new List<GroupRight>(); 
     Rights = new List<RightHeader>(); 
    } 
    public GroupHeader(string name, string description, IList<RightHeader> rights) 
     : this() 
    { 
     Name = name; 
     Description = description; 
     Rights = rights; 

     if (rights != null) 
      foreach (RightHeader right in rights) 
       AddRight(right, 1); 
    } 

    public virtual void AddRight(RightHeader newRight, decimal rightValue) 
    { 
     GroupRight newGroupRight = new GroupRight(this, newRight, rightValue); 
     GroupRights.Add(newGroupRight); 
    } 
} 

public class GroupRight 
{ 
    public virtual GroupHeader Group { get; set; } 
    public virtual RightHeader Right { get; set; } 
    public virtual decimal RightValue { get; set; } 

    public GroupRight() 
    { 

    } 
    public GroupRight(GroupHeader group, RightHeader right, decimal rightValue) 
    { 
     Group = group; 
     Right = right; 
     RightValue = rightValue; 
    } 
} 

public class RightHeader 
{ 
    public virtual decimal Num { get; private set; } 
    public virtual string Name { get; set; } 
    public virtual string Description { get; set; } 
    public virtual IList<GroupRight> GroupRights { get; set; } 

    public RightHeader() 
    { 

    } 
    public RightHeader(decimal num, string name, string description) 
    { 
     Num = num; 
     Name = name; 
     Description = description; 
    } 
} 

這些都是我一口流利的映射:

public class GroupHeaderMap : ClassMap<GroupHeader> 
{ 
    public GroupHeaderMap() 
    { 
     Table("GROUP_HEADER"); 
     Id(x => x.Id, "GROUP_ID"); 
     Map(x => x.Name, "GROUP_NAME").Unique(); 
     Map(x => x.Description, "GROUP_DESCRIPTION"); 
     HasMany(x => x.GroupRights) 
      .Table("GROUP_RIGHT_COMPOSITE") 
      .KeyColumns.Add("GROUP_ID") 
      .Cascade.AllDeleteOrphan(); 
    } 
} 

public class GroupRightMap : ClassMap<GroupRight> 
{ 
    public GroupRightMap() 
    { 
     Table("GROUP_RIGHT_COMPOSITE"); 
     CompositeId() 
      .KeyReference(x => x.Group, "GROUP_ID") 
      .KeyReference(x => x.Right, "RIGHT_NUM"); 

     Map(x => x.RightValue, "RIGHT_VALUE").Not.Nullable(); 
    } 
} 

public class RightHeaderMap : ClassMap<RightHeader> 
{ 
    public RightHeaderMap() 
    { 
     Table("RIGHT_HEADER"); 
     Id(x => x.Num, "RIGHT_NUM"); 
     Map(x => x.Name, "RIGHT_NAME"); 
     Map(x => x.Description, "RIGHT_DESCRIPTION"); 

     HasMany(x => x.GroupRights) 
      .Inverse() 
      .Table("GROUP_RIGHT_COMPOSITE") 
      .KeyColumn("RIGHT_NUM"); 
    } 
} 

每當我跑我的單元測試,試圖增加一個新的頁眉,GroupRight和RightHeader到我的數據庫我得到以下錯誤:

NHibernate.Exceptions.GenericADOException:無法插入:[Business.Objects.GroupRight#Business.Objects.GroupRight] [SQL:INSERT INTO GROUP_RIGHT_COMPOSITE(RIGHT_VALUE,GROUP_ID,RIGHT_NUM)VALUES(?,?,?)] --- > System.Data.SqlClient.SqlException:INSERT語句與FOREIGN KEY約束「FK_GROUP_RIGHTS_RIGHTS」衝突。衝突發生在數據庫「TEST」,表「dbo.RIGHT_HEADER」,列'RIGHT_NUM'。 該聲明已被終止。

我敢肯定,發生這種情況是因爲我創建的RIGHT_HEADER記錄不在數據庫中,它違反了外鍵約束,但我不知道如何映射它,以便NHibernate會先插入RIGHT_HEADER然後嘗試創建GROUP_RIGHT_COMPOSITE記錄。

編輯: 我使用的單元測試如下:

[TestMethod()] 
    public void GroupHeaderAddTest() 
    { 
     RightHeader newRight = new RightHeader(1, "Some Right", "Allows user to do something"); 
     GroupHeader newGroup = new GroupHeader("Administrators", "Administrative group", null, null); 
     newGroup.AddRight(newRight, 1); 

     using (NHibernate.ISession session = SessionOrigin.Current.GetSession()) 
     { 
      using (NHibernate.ITransaction tran = session.BeginTransaction()) 
      { 
       session.SaveOrUpdate(newGroup); 
       tran.Commit(); 
      } 

      GroupHeader foundGroup = session.CreateCriteria<GroupHeader>() 
           .Add(Example.Create(newGroup)) 
           .UniqueResult<GroupHeader>(); 

      Assert.IsNotNull(foundGroup, "Group should not be null"); 
      Assert.AreEqual<GroupHeader>(newGroup, foundGroup); 
     } 
    } 
+0

你可以發佈你的單元測試嗎? – 2010-11-08 19:54:48

+0

我已經在末尾的編輯部分發布了我在上面使用的測試。 – 2010-11-08 20:23:39

回答

0

我能得到這個工作的唯一方法是改變我的映射GroupRight以下幾點:

public class GroupRightMap : ClassMap<GroupRight> 
{ 
    public GroupRightMap() 
    { 

     Table("GROUP_RIGHT_COMPOSITE"); 
     CompositeId() 
      .KeyReference(x => x.Group, "GROUP_ID") 
      .KeyReference(x => x.Right, "RIGHT_NUM"); 

     References(x => x.Group, "GROUP_ID") 
      .Not.Update() 
      .Not.Insert() 
      .Cascade.All(); 

     References(x => x.Right, "RIGHT_NUM") 
      .Not.Update() 
      .Not.Insert() 
      .Cascade.All(); 

     Map(x => x.RightValue, "RIGHT_VALUE").Not.Nullable(); 
    } 
}