2012-01-16 19 views
7

Myślę, że brakuje mi czegoś koncepcyjnego odnośnie NHibernate. Mam obiekt Instrument, który mapuje do tabeli instruments w mojej bazie danych. Mam również obiekt BrokerInstrument, który mapuje do mojej tabeli brokerInstruments w mojej bazie danych. brokerInstrumnets to tabela podrzędna o numerze instruments. Moje zajęcia wyglądać następująco:Cykl życia obiektu w 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; } 
} 

W moim badanej jednostki, jeśli odzyskać to Instrument z bazy danych, a następnie usunąć go z ISession.Delete, jest on usuwany z bazy danych wraz z dziećmi (mam kaskada wszystko włączone w moim pliku odwzorowania). Model Instrument nadal jednak istnieje w pamięci. Na przykład:

[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 

    } 

Co jest najlepsze praktyki dotyczące obiektu w pamięci? Jestem teraz w niespójnym stanie, ponieważ mam w pamięci obiekt Instrument, który nie istnieje w bazie danych. Jestem początkującym programistą, więc pełne odpowiedzi są bardzo szczegółowe.

Odpowiedz

2

Kilka rzeczy. Twoje _sesje są w efekcie twoją jednostką pracy. Cała praca, którą tu robisz, polega na usuwaniu instrumentu i. Może owinąć ten kod w użyciu (_session).

Kiedy robisz swoje twierdzenia. Zrób nową sesję do sprawdzania pobierania.

Co do obiektu "i" - po pierwsze - nie należy go nazywać, ponieważ powinien być używany tylko do liczników pętli. Po drugie, w tym stwierdzeniu Assert.That(i.BrokerInstruments.Count, Is.EqualTo(0)) liczba i.BrokerInstruments niekoniecznie zostanie zmieniona, chyba że twoja implementacja dla IInstrumentRepo.Delete (Instrument someInstrument) jawnie ustawia someInstrument na wartość null.

Mam nadzieję, że to trochę pomaga.

0

Jeśli usuniesz Instrument przez instruments.Delete<Instrument>(i); Nhibernate usunie obiekt i jego zbiory z pamięci podręcznej pierwszego poziomu i sprawiają, że indywidualny i obiekty pozostają w pamięci jako indywidualny, jeśli są potrzebne, aby usunąć obiekt z pamięci trzeba po usuwać do sprawdzić, czy sesja zawierać usuniętego obiektu i ręcznie usunąć z pamięci, można postępować tak:

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

jednak pamiętać Net wykorzystuje śmieciarza, więc ustawienie go na null nie znaczy, że zniknął z pamięci od razu, od sprzątacza zależy, jak go usunąć.

Powiązane problemy