NHibernate cascade ="all-delete-orphan"正在删除非孤立的行

Phi*_*rdt 3 c# nhibernate fluent-nhibernate

当使用cascade ="all-delete-orphan"时,NHibernate正在删除一个没有孤立的子行 - 它只是被移动到一个新的父级.

using (var session = sessionFactory.OpenSession())
{
    using (var transaction = session.BeginTransaction())
    {
        // Get the store we're moving him to 
        Store newStore = session.QueryOver<Store>().Where(...).SingleOrDefault();

        // Get existing employee 
        Employee jack = session.QueryOver<Employee>().Where(...).SingleOrDefault();

        // Do the move
        jack.Store.Staff.Remove(jack);
        jack.Store = newStore;
        jack.Store.Staff.Add(jack);

        transaction.Commit(); 
    }
}
Run Code Online (Sandbox Code Playgroud)

提交时,会生成一个DELETE语句以从数据库中删除"jack".如果'jack'实际上已经成为孤儿,这种行为是有道理的,但他现在应该乐意分配到他的新店.

如果我将级联更改为"all",则会生成预期的UPDATE语句,并且可以按预期快速重新分配"jack".但是,这会导致真正的孤立行保留在数据库中,这是不可接受的.

这是一个错误还是我做错了什么?

以下是课程:

public class Store
{
    public virtual Guid Id { get; private set; }
    public virtual string Name { get; set; }
    public virtual IList<Employee> Staff { get; set; }
}

public class Employee
{
    public virtual Guid Id { get; private set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual Store Store { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

和FluentNHibernate映射:

public class EmployeeMap : ClassMap<Employee>
{
    public EmployeeMap()
    {
        Id(x => x.Id).GeneratedBy.Guid();
        Map(x => x.FirstName);
        Map(x => x.LastName);
        References(x => x.Store);
    }
}

public class StoreMap : ClassMap<Store>
{
    public StoreMap()
    {
        Id(x => x.Id).GeneratedBy.Guid();
        Map(x => x.Name);
        HasMany(x => x.Staff)
          .Inverse()
          .Cascade.AllDeleteOrphan();
    }
}
Run Code Online (Sandbox Code Playgroud)

UPDATE

在对此进行了一些测试之后,它似乎确实是一个错误,因为加载对象的顺序会改变结果(请注意,在这两种情况下,移动员工都按上述方式完成):

1)加载存储B,加载存储A,在A.Staff中查找员工,将员工移动到B ==> 删除员工(不抛出任何异常,不重新插入员工)

2)加载存储A,加载存储B,在A.Staff中查找员工,将员工移动到B ==> ObjectDeletedException(删除的对象将通过级联重新保存(从关联中删除已删除的对象))

第二种情况似乎是由@Cole W引用并在这里这里讨论的场景以及NHibernate中孤立处理的已知限制.

但是,第一种情况似乎是一个错误.根据我的理解,不应该有一个场景,其中加载对象的顺序改变了NHibernate所做的数据库更改.它似乎是一个可能导致数据丢失的错误.

更新2

鉴于依赖于加载顺序的不一致行为和数据丢失的可能性,我已将此记录为NHibernate JIRA中错误.错误报告具有完整的代码和映射来演示问题.

Col*_*e W 5

这实际上似乎是使用NHibernate的常见问题.查看这些文章,看看它们是否对您有所帮助.

看看这篇SO文章:Fluent NHibernate异常在集合之间移动对象

该文章还链接了Fabio Maulo的这篇文章:http://fabiomaulo.blogspot.com/2009/09/nhibernate-tree-re-parenting.html