I think I'm missing something conceptually regarding NHibernate. I have an Instrument
object which maps to an instruments
table in my database. I also have a BrokerInstrument
object which maps to my brokerInstruments
table in my database. brokerInstrumnets
is a child table of instruments
. My classes look like:
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; }
}
In my unit test, if I retrieve an Instrument
from the database and then delete it with ISession.Delete
, it is removed from the database along with the children (I have cascade-all switched on in my mapping file). The Instrument
however still exists in memory. For example:
[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
}
What is best practise regarding the object in memory? I am now in an inconsistent state because I have an Instrument
object in memory which does not exist in the database. I'm a novice programmer so verbose answers with links are much appreciated.
A few things. Your _session is in effect your unit of work. All the work you are doing here is deleting instrument i. Maybe wrap that code in a using(_session).
When you are doing your assertions. Make a new session to do the retrieval checks.
As regards the "i" object - firstly - don't name it i as that should be only used for loop counters. Secondly, in this assertion Assert.That(i.BrokerInstruments.Count, Is.EqualTo(0))
the count of i.BrokerInstruments would not necessarily be changed unless your implementation for IInstrumentRepo.Delete(Instrument someInstrument) is explicitly setting someInstrument to null.
Hope this helps a bit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With