2012-01-16 103 views
7

我想我在概念上對NHibernate缺少一些東西。我有一個Instrument對象,它映射到我的數據庫中的instruments表。我也有一個BrokerInstrument對象,它映射到我的數據庫中的我的brokerInstruments表。 brokerInstrumnetsinstruments的子表。我班的樣子:NHibernate中的對象生命週期

public class Instrument : Entity 
{ 
    public virtual string Name { get; set; } 
    public virtual string Symbol {get; set;} 
    public virtual ISet<BrokerInstrument> BrokerInstruments { get; set; } 
    public virtual bool IsActive { get; set; }   
} 

public class BrokerInstrument : Entity 
{ 
    public virtual Broker Broker { get; set; } 
    public virtual Instrument Instrument { get; set; } 
    public virtual decimal MinIncrement { get; set; } 
} 

在我的單元測試,如果我從數據庫中檢索的Instrument,然後用ISession.Delete刪除它,它是從數據庫中與孩子們一起刪除(我有級聯全部開啓在我的映射文件中)。然而Instrument仍然存在於內存中。例如:

[Test] 
    public void CascadeTest() 
    { 
     int instrumentId = 1; 
     IInstrumentRepo instruments = DAL.RepoFactory.CreateInstrumentRepo(_session); 
     Instrument i = instruments.GetById<Instrument>(instrumentId); // retrieve an instrument from the db 
     foreach (BrokerInstrument bi in i.BrokerInstruments) 
     { 
      Debug.Print(bi.MinIncrement.ToString()); // make sure we can see the children 
     } 

     instruments.Delete<Instrument>(i); // physically delete the instrument row, and children from the db 

     IBrokerInstrumentRepo brokerInstruments = DAL.RepoFactory.CreateBrokerInstrumentRepo(_session); 
     BrokerInstrument deletedBrokerInstrument = brokerInstruments.GetById<BrokerInstrument>(1); // try and retrieve a deleted child 
     Assert.That(instruments.Count<Instrument>(), Is.EqualTo(0)); // pass (a count in the db = 0) 
     Assert.That(brokerInstruments.Count<BrokerInstrument>(), Is.EqualTo(0)); // pass (a count of children in the db = 0) 
     Assert.That(i.BrokerInstruments.Count, Is.EqualTo(0)); // fail because we still have the i object in memory, although it is gone from the db 

    } 

關於內存中對象的最佳做法是什麼?我現在處於不一致的狀態,因爲我在內存中有一個Instrument對象,它在數據庫中不存在。我是一個新手程序員,所以我們非常感謝帶有鏈接的詳細答案。

回答

2

有幾件事。你的工作實際上就是你的工作單位。你在這裏所做的所有工作都是刪除儀器i。也許在使用(_session)中包裝該代碼。

當你在做你的斷言。做一個新的會話來做檢索檢查。

關於「我」的對象 - 首先 - 不要命名我,因爲它應該只用於循環計數器。其次,在這個斷言Assert.That(i.BrokerInstruments.Count, Is.EqualTo(0)) i.BrokerInstruments的計數不一定會改變,除非你的實施IInstrumentRepo.Delete(樂器someInstrument)明確設置someInstrument爲null。

希望這會有所幫助。

0

如果通過instruments.Delete<Instrument>(i);刪除儀器NHibernate的將刪除從第一級高速緩存中的對象和它的集合,使其超脫和對象保留在內存中分離,如果需要從內存中刪除對象,你需要刪除後到檢查是否包含會話刪除的對象,並從內存中手動刪除,你可以這樣進行:

if (!Session.Contains(instruments)) 
{ 
    instruments= null; 
} 

記住,雖然.NET使用垃圾收集器,因此將其設置爲空並不意味着它從內存中消失的時候了,垃圾收集器在達到它時將其刪除。