2013-04-28 35 views
1

假設我有下一個映射父集合多個查詢:添加子項NHibernate的包,超過必要

public class A : Entity<A> 
{ 
    private readonly IList<B> _bs = new List<B>(); 
    public virtual string AProp { get; set; } 
    public A(string aprop) 
    { 
     AProp = aprop; 
    } 
    protected A() 
    { 
    } 

    public virtual IEnumerable<B> Bs 
    { 
     get { return _bs; } 
    } 

    public virtual void AddBEntity(B bEntity) 
    { 
     bEntity.A = this; 
     _bs.Add(bEntity); 
    } 
} 

    public class AMap : EntityMap<A> 
    { 
     public AMap() 
     { 
      Map(x => x.AProp).Not.Nullable(); 
      HasMany(x => x.Bs) 
       .Access.ReadOnlyPropertyThroughCamelCaseField(Prefix.Underscore) 
       .Inverse().Cascade.All().AsBag(); 
     } 
    } 

而接下來的子類和它的映射:

public class B: Entity<B> 
     { 
      public virtual string BProp { get; set; } 
      public virtual A A { get; set; } 
     } 

     public class BMap : EntityMap<B> 
     { 
      public BMap() 
      { 
       Map(x => x.BProp).Not.Nullable(); 
       References(x => x.A).Cascade.All(); 
      } 
} 

假設我需要將孩子添加到現有父級。我希望在SQL中插入一個已知的孩子的值和父母的ID。 我嘗試了不同的映射,但我不明白爲什麼我會加載一個代理對象來添加一個孩子,因爲NH profiler建議我這樣做。

enter image description here

回答

1

如果我正確理解你的問題你有一個代理的列表,並希望到一個或多個燒烤添加到每個A.如果這是不正確的,請告訴我們您的代碼在這裏裝載/創建作爲並添加Bs。

只要您調用任何公共方法,您的A代理就會被加載。在你的情況下,這很可能是AddBEntity方法或Bs屬性獲取器。 NHibernate無法知道你想要在那些方法和屬性中做什麼,因此總是需要初始化代理。

我現在還不完全確定,但我認爲您可以通過執行類似以下操作來加載您的A代理來插入新的B。基本上只要確保你永遠不會在A代理上調用方法。

B newB = new B(); 
newB.A = someAProxy; 
session.Save(newB); 
+0

是的,我測試了這一點,它有幫助,但有些情況下,當域假設雙向關聯,你需要添加鏈接到兩端。 – 2013-05-06 18:08:39

+0

@Hohhi如果您在保存新Bs後第一次訪問'Bs'集合,它們將會在那裏,所以這應該不成問題。如果該集合在保存新Bs之前已經加載,則只需將它們添加到'Bs'集合中即可。 – cremor 2013-05-07 07:16:51

+0

是的,但如果我沒有清除會話清除,我可以得到骯髒的會議,不是嗎? – 2013-05-07 09:21:56