Жизненный цикл объекта в NHibernate - PullRequest
7 голосов
/ 16 января 2012

Я думаю, что я концептуально что-то упускаю в отношении NHibernate.У меня есть объект Instrument, который отображается в таблицу instruments в моей базе данных.У меня также есть объект BrokerInstrument, который отображается в моей таблице brokerInstruments в моей базе данных.brokerInstrumnets является дочерним столом instruments.Мои классы выглядят так:

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 ]

2 голосов
/ 16 января 2012

Несколько вещей. Ваша сессия фактически является вашей единицей работы. Вся работа, которую вы здесь делаете, это удаление инструмента i. Может быть, обернуть этот код в использование (_session).

Когда вы делаете свои утверждения. Создайте новый сеанс для проверки поиска.

Что касается объекта "i" - во-первых, не называйте его i, поскольку он должен использоваться только для счетчиков циклов. Во-вторых, в этом утверждении Assert.That(i.BrokerInstruments.Count, Is.EqualTo(0)) счетчик i.BrokerInstruments не обязательно будет изменен, если ваша реализация для IInstrumentRepo.Delete (Instrument someInstrument) явно не устанавливает someInstrument в значение null.

Надеюсь, это немного поможет.

0 голосов
/ 17 января 2012

Если вы удалите Инструмент с помощью instruments.Delete<Instrument>(i); Nhibernate удалит объект и его коллекции из кэша первого уровня и отключит его, а объекты останутся в памяти как отсоединенные, если вам нужно удалить объект из памяти, который вам нужен после удалениячтобы проверить, содержит ли сессия удаленный объект и удалить его из памяти вручную, вы можете выполнить следующее:

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

, хотя помните, что .Net использует сборщик мусора, поэтому установка его на ноль не означает, что он ушел из памятиСразу же, сборщик мусора может удалить его, когда доберется до него.

...