NHibernate批量插入无法正常工作

时间:2011-06-03 08:12:05

标签: .net nhibernate

我正在尝试将NH批量插入工作以将一些旧数据迁移到我们的新数据库。对于测试样本,我已经配置了批量大小,如下所示:

<property name="adonet.batch_size">25</property>

并且在无状态会话中,我在提交事务之前插入了大约1000个对象。对象ID策略是guid.comb,映射如下:

<id name="Id" access="field.camelcase-underscore" type="guid" column="id">
  <generator class="guid.comb"/>
</id>

使用NH Profiler我可以看到所有对象都是作为单独的语句插入而不是批处理的,所有这些对象看起来都很像:

INSERT INTO Buddies
       (id)

VALUES('81c7d3be-d718-45a4-86fe-9ef700b7ad55'/ * @ p0_0 * /)

可能是什么原因,我应该怎么做才能让批处理工作?

3 个答案:

答案 0 :(得分:1)

试试看:

NHibernate 2.1.0.4000 doesn't seem to like batch insert

我认为这也很有用:

http://fabiomaulo.blogspot.com/2009/02/nh210-generators-behavior-explained.html

在本文中,在他使用的最后一个例子中:

<id type="int">
   <generator class="identity"/>
</id>

这似乎是关键..你试过吗?

答案 1 :(得分:1)

插入批处理仅适用于Session,而不适用于StatelessSession。

立即无状态插入。

答案 2 :(得分:1)

DML操作的批处理与无状态会话一起使用,但它与使用state-full会话批处理有相同的限制,还有一些额外的:

  • 当这些实体具有插入后检索的ID时,它不能批量实体插入,例如identity generator。
  • 它不能批量插入,更新或删除跨越许多表的实体。
  • 可能无法使用乐观锁定。 (这里有不同的情况,具体取决于版本的生成方式。)
  • 此外,由于它是无状态的,因此不会尝试重新组合相同的实体类操作以将它们一起批处理。一旦您启动另一个操作(从插入切换到更新示例)或开始在另一种实体上操作,将刷新上一批操作。因此,当使用无状态会话进行操作时,如果操作经常混合,则批处理确实不起作用。由开发人员重新组合它们。

comment的另一个答案中看到,您的实体跨越多个表格。它不能分批。

以下是对其工作原理的简化和不完整的解释。 DML批处理器通过插入或更新或删除命令来工作,其中包含其值的参数。它存储它及其参数值。在它接收的下一个命令中,它检查它是否与前一个匹配。如果是,则存储其参数值。如果是另一个命令,则刷新上一批并存储新命令。

这就是为什么跨越多个表的实体无法批处理的原因:它上面的每个操作都意味着许多命令,导致批处理器在每次操作时刷新。在某些边缘情况下,您插入一个不跨越多个表的基本非抽象实体,然后是跨越多个表的后代实体,您可以看到第一个后代实体的基表插入与基础实体的插入进行批处理。但这是一个极端情况,实际上并不值得尝试利用,因为它仅适用于基本实体操作之后的第一个许多表实体,而不适用于后续操作。