2012-01-16 64 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使用垃圾收集器,因此将其设置为空并不意味着它从内存中消失的时候了,垃圾收集器在达到它时将其删除。