2

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

我觉得我在这里缺少一些东西,因为在删除它之前必须获取一个对象是不对的。有什么想法吗?

4

1 回答 1

2

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

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

根据您的应用程序,应在更高级别启动 Session 并跨多个事务使用。为每个事务创建和处置 Session 是不必要的开销。

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

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

于 2013-05-27T18:56:41.487 回答