刷新会话时SQL语句的Nhibernate顺序

刷新会话时SQL语句的Nhibernate顺序,nhibernate,hibernate,Nhibernate,Hibernate,根据NHibernate文档,在刷新会话时,SQL语句按以下顺序发出: 所有实体插入,使用ISession.Save()以相同的顺序保存相应的对象 所有实体更新 所有集合删除 所有集合元素的删除、更新和插入 所有集合插入 所有实体删除,按照使用ISession.Delete()删除相应对象的相同顺序 为什么它是按这个顺序强制执行的?有没有办法改变它,使语句按照我给它们的相同顺序执行?它是按这个顺序执行的,因为它是最安全的 不,你不能改变顺序。而且,您从未给NHibernate任何命令:您只是

根据NHibernate文档,在刷新会话时,SQL语句按以下顺序发出:

  • 所有实体插入,使用ISession.Save()以相同的顺序保存相应的对象
  • 所有实体更新
  • 所有集合删除
  • 所有集合元素的删除、更新和插入
  • 所有集合插入
  • 所有实体删除,按照使用ISession.Delete()删除相应对象的相同顺序

为什么它是按这个顺序强制执行的?有没有办法改变它,使语句按照我给它们的相同顺序执行?

它是按这个顺序执行的,因为它是最安全的

不,你不能改变顺序。而且,您从未给NHibernate任何命令:您只是为持久性标记实体;NHibernate自动确定要执行的操作


如果您认为需要对单个SQL操作进行更多控制,可以使用
IStatelessSession
而不是常规的
ISession
。您会丢失NH自动执行的所有操作(延迟加载、缓存、脏跟踪),但您可以(必须)明确指出何时插入、删除或更新记录。

您不能更改NHibernate根据上述操作生成SQL的顺序,但您可以将工作单元分块

例如:

使用(var transaction=Session.BeginTransaction())
{
var company=Session.QueryOver().First();
var employee=newemployee{ID=Guid.NewID()};
company.Employees.Add(员工);
Session.Flush();
var carSpace=new CarParkingSpace{EmployeeID=employee.ID};
Session.Save(carSpace);
Commit();
}

通过添加Session.Flush()-到该点的所有内容都将推送到事务中。如果没有它,NHibernate会试图为一个尚未存在的员工创建一个停车位。

我对此很感兴趣。为什么你想要一个不同的顺序,你想达到什么目的?好吧,不用太多细节,我有一个多对多表(带有复合pk),我想先删除它,然后在保存父表时重新插入;我在父集合上设置了inverse=true,因此我必须自己管理保存,但由于插入发生在删除之前,如果需要重新保存旧的多对多零件,我会遇到约束冲突。我只在NH玩了一天左右,仍在努力解决细节问题。这可能是最安全的,但你需要记住它的每一步,即使是通常简单的删除->插入也会变得棘手。(对于具有唯一属性/列的记录,s.Delete;s.Save将不起作用)。
using(var transaction = Session.BeginTransaction())
{
    var company = Session.QueryOver<Company>().First();
    var employee = new Employee{ ID = Guid.NewID() };
    company.Employees.Add(employee);
    Session.Flush();    

    var carSpace = new CarParkingSpace { EmployeeID = employee.ID };
    Session.Save(carSpace);

    transaction.Commit();
}