2013-12-13 47 views
2

我試圖&新的子項保存新的父項舊的數據庫功能NHibernate保存child.parentid = parentId的新父母及兒童

我得到我的數據就好了,當我保存它保存父母和孩子。然而孩子的SillyNameParentId總是0

表結構我不能改變,所以我必須弄清楚如何使這項工作。

這裏是生成的SQL

NHibernate: INSERT INTO SillyNameParent(Description, Active) VALUES (@p0, @p1); select SCOPE_IDENTITY();@p0 = 'Test' [Type: String (1073741823)], @p1 = True [Type: Boolean (0)] NHibernate: INSERT INTO SillyChild (SillyNameCategoryId, sillyNameParentid) VALUES (@p0, @p1); select SCOPE_IDENTITY();@p0 = 0 [Type: Int32 (0)], @p1 = 1 [Type: Int32 (0)]

最後,我想@ P1被設置爲SillyNameParentId/PARENTID

表:

SillyNameParent 
    Column PK-IsIdentity: ParentId 
    Column varchar(255): Description 
    Column bit: Active 

SillyChild //I'm a lookup table 
    Column int IsIdentity: Id 
    Column int PK: SillyNameParentId 
    Column int PK: SillyNameCategoryID 

機型:

public class SillyNameParent: Entity 
{ 
    public SillyNameParent() 
    { 
     Children= new List<SillyChild>(); 
    } 
    public virtual string AreaOfConcernDesc { get; set; } 
    public virtual bool Active { get; set; } 
    public virtual IList<SillyChild> Children{ get; set; } 
} 

public class SillyChild: Entity 
{ 
    public virtual int SillyNameParentId { get; set; } 
    public virtual int SillyNameCategoryId{ get; set; } 
    public virtual SillyNameParent Parent { get; set; } 

} 

MAPS:

public class SillyNameParentMap : IAutoMappingOverride<SillyNameParent> 
{ 
    public void Override(AutoMapping<SillyNameParent> mapping) 
    { 
     mapping.Table("SillyNameParent"); 
     mapping.Id(x => x.Id).Column("ParentId").GeneratedBy.Identity(); 
     mapping.Map(x => x.Description).Not.Nullable(); 
     mapping.Map(x => x.Active).Nullable(); 
     mapping.HasMany(x => x.children) 
      .Cascade.All() 
      .KeyColumn("SillyNameParentId") 
      .Not 
      .LazyLoad(); 
    } 
} 

public class SillyChildMap: IAutoMappingOverride<SillyChild> 
{ 
    public void Override(AutoMapping<SillyChild> mapping) 
    { 
     mapping.Table("SillyChild"); 
     mapping.Id(x => x.Id).Column("Id").GeneratedBy.Identity(); 
     mapping.Map(x => x.SillyNameParentId).Not.Nullable(); 
     mapping.Map(x => x.SillyNameCategoryId).Not.Nullable(); 
     mapping.HasOne(x => x.Parent).ForeignKey("SillyNameParentId"); 
    } 
} 

回答

1

這裏是一個變通......因爲身份被我猜我需要保存孩子之前保存父DB設置。有一個更好的方法,但是這裏是我想出的

public T SaveReturnEntity(T entity) 
    { 
     try 
     { 
      this.Session.Save(entity); 
     } 
     catch 
     { 
      if (this.Session.IsOpen) 
      { 
       this.Session.Close(); 
      } 

      throw; 
     } 

     this.Session.Flush(); 
     return entity; 
    } 



return _sillyParent.SaveReturnEntity(sillyNameParent) != null; 


[Test] 
    public void Save_sillyParent() 
    { 
     var sillyService = ServiceMiniMart.CreateSillyParent(); 

     var filter = new sillyQueryFilter(); 
     { 
      CategoryId = 1 
     };  
     var snp= new SillyNameParent 
      { 
       Active = true, 
       Description= "Test" 
      }; 
     if (sillyService.SaveSillyParent(snp)) 
     { 
      snp.Category = new List<SillyChild> 
       { 
        new SillyChild 
         { 
          SillyNameParentId= snp.Id, 
          SillyNameCategoryId= filter.CategoryId.Value, 
          Parent = snp 
         } 
       }; 
     } 


     var a = sillyService.SaveSillyParent(snp); 
    } 
3

我會說,你幾乎在那裏。就在映射父/子應該是這樣的:

SillyNameParentMap:

public void Override(AutoMapping<SillyNameParent> mapping) 
{ 
    ... 
    mapping.HasMany(x => x.Children) 
     .Cascade.All() 
     .KeyColumn("SillyNameParentId") 
     .Inverse() // this is the way how to manage insertions 
     .Not 
     .LazyLoad(); 

SillyChildMap:

public void Override(AutoMapping<SillyChild> mapping) 
{ 
    ... 
    mapping.References(x => x.Parent) 
     .Column("SillyNameParentId"); 

這個映射會在正確的插入結束了,只是這樣的:

var parent = new SillyNameParent(); 
parent... // set properties 

var child = new SillyChild(); 
child... // set properties 

parent.Children.Add(child); // parent knows about child 
child.Parent = parent; // always do set the relation both ways 

sillyService.SaveSillyParent(snp) 

編輯:選擇2問題

異常說的是雙列映射。對於INSERT或UPDATE,這是一個問題。但隨着NHibernate的,我們可以很容易地解決這個問題:

mapping.Map(x => x.SillyNameParentId) 
    .Not.Nullable() 
    .Not.Insert() 
    .Not.Update(); 
mapping.References(x => x.Parent) 
    .Column("SillyNameParentId"); 

所以,現在我們已經映射兩個屬性(參考家長和INT表示)。只有引用將用於INSERT,UPDATE。但兩者都可以用於選擇,過濾器/位置和順序...

+0

我已經試過用成功,當sillyChild使用mapping.Refrences我得到這個錯誤:Erro脫水屬性值... Parent,InnerException:Count = 2的SqlParameterCollection的索引2無效。 – WeisserHund

+0

我看不到錯誤?這是你的評論的一部分?親子關係非常平常。最平常的。它確實沒有「解決方法」。請提供更多信息..我們會找到解決方案。哇...我明白了。我會在一個小時內回來......並看看 –

+0

是的,我同意這是一種非常普通的關係,我使用這種模式很多。但是我在想,因爲這個數據庫是遺留的,並且父表的ID列的名稱與引用父名稱列的子查找表列的名稱不同,再加上DB設置標識可能是模式不起作用的原因。感謝您的職位,並提前感謝您進一步調查 – WeisserHund