2011-10-03 32 views
1

我擁有包含對象列表的對象。nhibernate。在同一會話中創建袋後爲空

public class Product: IProduct 
{ 
    public virtual long  Id { get; set; } 
    public virtual string Name { get; set; } 

    public virtual IList<IFunction> Functions { get; set; } 
} 

public class Function : IFunction 
{ 
    public virtual long  Id { get; set; } 
    public virtual string Name { get; set; } 

    public virtual IProduct Product { get; set; } 
} 

映射對象的列表(IList的<■功能>):

<bag name="Functions" cascade="all" table="T_WEBFUNCTIONS" lazy="false"> 
    <key column="PRODUCT_ID" /> 
    <one-to-many class="Function" /> 
</bag> 

代碼:

我嘗試建立產品

public IProduct SetProduct(string productName) 
    { 
     // Product repository, which have nhibernate opened session (ISession) 
     IDBRepository<IProduct> rep = Repository.Get<IProduct>(); 

     // Create new object of product 
     rep.Create(new Product() { Name = productName }); 

     // get created object by name 
     prod = rep.Query().Where(x => x.Name == productName).SingleOrDefault(); 

     // I HAVE ISSUE HERE 
     // prod.Functions == NULL. It must be a new List<Function>() 
     // Nhibernate don't create empty list for me and this property always null 

     return prod; 
    } 

而是一個新的對象。當nhibernate會話關閉並再次打開時,該列表將被創建並且有0個項目。

如果我在同一個會話中創建一個對象(產品)並在創建後得到它,bag將爲空。數據倉庫

public class DBRepository<T> : IDBRepository<T> 
{ 
    protected ISession CurrentSession; 

    public DBRepository(ISession session) 
    { 
     CurrentSession = session; 
    } 

    public void Create(T obj) 
    { 
     var tmp = CurrentSession.BeginTransaction(); 
     CurrentSession.Save(obj); 
     tmp.Commit(); 
    } 
} 

回答

3

功能當你調用new Product(),你的代碼實例化對象和列表<>屬性開始生活爲空。 NHibernate無法幫助你 - 這就是你決定要做的事(不覆蓋默認的c'tor)。當您提交事務時,NHibernate的一級緩存(簡短說明here)會保存您的對象,因此當您在同一個打開的會話中,您通過其ID請求該對象時,NHibernate會跳過從數據庫獲取實體併爲您提供相同服務實例化對象。你可以用Object.ReferenceEquals(prodYouCreated, prodRetrievedFromRepository)進行測試。

當您關閉1級高速緩存被清除了會議,並在下一次查詢的NHibernate獲取數據,並建立對象本身 - 它選擇給你回零長度列表,而不是空。這是默認行爲。

希望這有助於
Jonno

+0

THX。這有所幫助。嘗試使用表達式'rep.Create(new Product(){Name = productName,Functions = new List ()})'。工作得很好 – Kronos

+0

不用擔心。 絕對比使用'函數=新列表()'更好,而不是改變! 剛纔我發現「跳過從數據庫中獲取實體」在某些情況下是正確的,但在這裏不是。 在這種情況下,信息已經從數據庫中檢索出來(這取決於在存儲庫上完成的查詢),所以保存的是NHibernate重新構建對象。 – Jonno