FluentNHibernate не удаляет дочернюю сущность даже с AllDeleteOrphan

У меня есть сущность Car, которая обладает дверями. Когда автомобиль удален, двери должны быть удалены также, потому что они не имеют смысла сами по себе. Вот отображение в FluentNHibernate.

public class CarMap : ClassMap<Car>
{
    public CarMap()
    {
        Id(x => x.CarId).GeneratedBy.Assigned();
        HasMany(x => x.Doors).Cascade.AllDeleteOrphan();
    }
}

public class DoorMap : ClassMap<Door>
{
    public DoorMap()
    {
        Id(x => x.DoorId);
        References(x => x.Car);
    }   
}

Метод Delete внутри CarDao выглядит так:

public void Delete(Car car)
{
    using (ISession session = NHibernateHelper.OpenSession())
    using (ITransaction transaction = session.BeginTransaction())
    {
        session.Delete(car);
        transaction.Commit();
    }
}

Тем не менее, при удалении автомобиля таким образом, двери не удаляются, а carId устанавливается на NULL. Я думал, что Cascade.AllDeleteOrphan(), позаботится об удалении детей (Doors). Мне пришлось переделать метод удаления к этому:

public void Delete(Car car)
{
    using (ISession session = NHibernateHelper.OpenSession())
    using (ITransaction transaction = session.BeginTransaction())
    {
        var entity = session.Get<Car>(car.CarId);
        if (entity != null)
        {
            session.Delete(entity);
            transaction.Commit();
        }
    }
}

Я чувствую, что здесь что-то упускаю, потому что не правильно искать объект перед его удалением. Какие-нибудь мысли?

1 ответ

Решение

Вы создаете и удаляете сеанс по каждому запросу. В вашем первом методе Delete конкретный сеанс не совпадает с сеансом, в котором изначально загружался объект Car, в который вы передаете. Поэтому он не имеет ссылки на объекты Door, чтобы удалить их, когда вы запрашиваете удаление Car.

Во втором методе сеанс загружает автомобиль и поэтому имеет ссылку на дочерние объекты (даже если дочерние объекты не загружены полностью, nHibernate загрузит прокси-сервер), это позволяет сеансу каскадно удалять объекты на дверях при удалении. машина.

В зависимости от вашего приложения сеанс должен ускоряться на более высоком уровне и использоваться для нескольких транзакций. Это ненужные накладные расходы для создания и утилизации сеанса для каждой транзакции.

Я бы порекомендовал вам прочитать следующий пост об управлении сессиями в nHibernate:

http://nhforge.org/blogs/nhibernate/archive/2011/03/03/effective-nhibernate-session-management-for-web-apps.aspx

Другие вопросы по тегам