即使使用AllDeleteOrphan,FluentNHibernate也不会删除子实体

时间:2013-05-27 17:21:21

标签: nhibernate fluent-nhibernate fluent-nhibernate-mapping all-delete-orphan

我有一个拥有门的汽车实体。当汽车被删除时,门也应该被删除,因为它们自己没有意义。 这是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);
    }   
}

CarDao中的Delete方法如下:

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

然而,当以这种方式删除汽车时,门不会被删除,但是carId被置为de NULL。我以为Cascade.AllDeleteOrphan()会照顾删除孩子(门)。我不得不将Delete方法重写为:

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 个答案:

答案 0 :(得分:2)

您正在为每个请求实例化并处理会话。在您的第一个Delete方法中,实例化的会话与最初加载您传入的Car对象的会话不同。因此,当您请求删除Car时,它不会引用Door对象以删除它们。

在你的第二个方法中,会话加载Car,因此引用了子对象(即使子对象未完全加载,nHibernate将加载代理),这允许该会话将删除级联到门对象当你删除汽车时。

根据您的应用程序,会话应在更高级别进行调整,并在多个事务中使用。为每个事务创建和处理会话是一种不必要的开销。

我建议您阅读以下有关nHibernate中会话管理的帖子:

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