Nhibernate 删除父级和子级而不进行级联
我的代码正在累积用户的对象删除和更新,然后尝试一次应用它们。在我遇到问题的情况下,业务要求只有在没有子项的情况下才删除父项,但必须手动删除子项 我可以用以下代码重现该问题: 映射:Nhibernate 删除父级和子级而不进行级联,nhibernate,parent-child,Nhibernate,Parent Child,我的代码正在累积用户的对象删除和更新,然后尝试一次应用它们。在我遇到问题的情况下,业务要求只有在没有子项的情况下才删除父项,但必须手动删除子项 我可以用以下代码重现该问题: 映射: 实体: 公共类SomeClass { 公共虚拟整数ID{get;set;} 公共虚拟字符串名称{get;set;} 公共虚拟父对象{get;set;} } 公共类父类 { 公共虚拟整数ID{get;set;} 公共虚拟字符串名称{get;set;} 公共虚拟ISet子项{get;set;} } 节目: 使用(v
实体:
公共类SomeClass
{
公共虚拟整数ID{get;set;}
公共虚拟字符串名称{get;set;}
公共虚拟父对象{get;set;}
}
公共类父类
{
公共虚拟整数ID{get;set;}
公共虚拟字符串名称{get;set;}
公共虚拟ISet子项{get;set;}
}
节目:
使用(var sessionFactory=cfg.BuildSessionFactory())
使用(var session=sessionFactory.OpenSession())
{
var p=新的SomeParent();
var obj=newsomeclass(){Parent=p};
session.Save(p);
session.Save(obj);
session.Flush();
}
使用(var sessionFactory=cfg.BuildSessionFactory())
使用(var session=sessionFactory.OpenSession())
使用(var tx=session.BeginTransaction())
{
foreach(会话中的var p.CreateCriteria().List())
{
删除(p);
}
foreach(会话中的var p.CreateCriteria().List())
{
删除(p);
}
session.Flush();
tx.Commit();
}
当我交换两个Delete()
循环时,这个例子就起作用了。在我的应用程序中,我不能随意影响用户按下删除按钮的顺序
如果我将cascade=“delete”
添加到one-to-many
映射中,此示例也会起作用。这违反了业务要求,即当父母仍有子女时,不能删除他们
我本以为NHibernate会帮我处理这个订单。尤其是在地图中已经有了所有必要的信息。我只是做错了什么,还是必须“手动”对删除进行正确排序,以便NHibernate对其进行检查
我正在使用NHibernate 3.2.0GA(从nuget构建3.2.0.4000)。我不理解您对NHibernate应该能够处理这种情况的期望。由于没有指定级联设置,因此必须自己处理删除 我的建议是跟踪集合中的删除,在验证数据之前不要发出NHibernate deletes。也就是说,为父对象和子对象创建MarkForDelete方法。当用户单击“删除”时,这些方法将对象添加到集合中 当用户准备提交事务时,遍历已标记为删除的子对象,将其从父对象的子对象集合中删除,并将其对父对象的引用设置为null。然后遍历标记为删除的父对象,并验证其子集合是否为空
如果数据有效,则可以删除父对象,并让级联设置(全部或全部删除孤立项)处理子记录。我不理解您期望NHibernate能够处理这种情况。由于没有指定级联设置,因此必须自己处理删除 我的建议是跟踪集合中的删除,在验证数据之前不要发出NHibernate deletes。也就是说,为父对象和子对象创建MarkForDelete方法。当用户单击“删除”时,这些方法将对象添加到集合中 当用户准备提交事务时,遍历已标记为删除的子对象,将其从父对象的子对象集合中删除,并将其对父对象的引用设置为null。然后遍历标记为删除的父对象,并验证其子集合是否为空
如果数据有效,则可以删除父对象,并让级联设置(全部或全部删除孤立项)处理子记录。在某种程度上,这种期望源于一个简单的事实,即NHibernate可以这样做,其他ORM也可以这样做。手动实现排序只是一个不切实际的最后解决方案。还有什么其他的orm可以做到这一点呢?如果反转设置在子对象映射上,NH的行为如何?即使NH可以做到这一点,它是否满足了您的要求,即所有仅与无子对象关联的父对象都可以被删除?此外,我执行删除操作。在某种程度上,这种期望植根于一个简单的事实,即NHibernate可以做到这一点,而其他orm也可以做到这一点。手动实现排序只是一个不切实际的最后解决方案。还有什么其他的orm可以做到这一点呢?如果反转设置在子对象映射上,NH的行为如何?即使NH可以做到这一点,它是否满足了您的要求,即所有仅与无子对象关联的父对象都可以被删除?此外,我执行删除操作。它们只是以错误的顺序提交到数据库。
<class name="SomeClass" >
<id name="ID">
<generator class="native" />
</id>
<property name="Name" />
<many-to-one name="Parent" not-null="true" />
</class>
<class name="SomeParent" >
<id name="ID">
<generator class="native" />
</id>
<property name="Name" />
<set name="Children" batch-size="100" inverse="true">
<key column="Parent" not-null="true" />
<one-to-many class="SomeClass" />
</set>
</class>
public class SomeClass
{
public virtual int ID { get; set; }
public virtual string Name { get; set; }
public virtual SomeParent Parent { get; set; }
}
public class SomeParent
{
public virtual int ID { get; set; }
public virtual string Name { get; set; }
public virtual ISet<SomeClass> Children { get; set; }
}
using (var sessionFactory = cfg.BuildSessionFactory())
using (var session = sessionFactory.OpenSession())
{
var p = new SomeParent();
var obj = new SomeClass() { Parent = p };
session.Save(p);
session.Save(obj);
session.Flush();
}
using (var sessionFactory = cfg.BuildSessionFactory())
using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
foreach (var p in session.CreateCriteria<SomeParent>().List<SomeParent>())
{
session.Delete(p);
}
foreach (var p in session.CreateCriteria<SomeClass>().List<SomeClass>())
{
session.Delete(p);
}
session.Flush();
tx.Commit();
}