我正在尝试将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 * /)
可能是什么原因,我应该怎么做才能让批处理工作?
答案 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会话批处理有相同的限制,还有一些额外的:
identity
generator。在comment的另一个答案中看到,您的实体跨越多个表格。它不能分批。
以下是对其工作原理的简化和不完整的解释。 DML批处理器通过插入或更新或删除命令来工作,其中包含其值的参数。它存储它及其参数值。在它接收的下一个命令中,它检查它是否与前一个匹配。如果是,则存储其参数值。如果是另一个命令,则刷新上一批并存储新命令。
这就是为什么跨越多个表的实体无法批处理的原因:它上面的每个操作都意味着许多命令,导致批处理器在每次操作时刷新。在某些边缘情况下,您插入一个不跨越多个表的基本非抽象实体,然后是跨越多个表的后代实体,您可以看到第一个后代实体的基表插入与基础实体的插入进行批处理。但这是一个极端情况,实际上并不值得尝试利用,因为它仅适用于基本实体操作之后的第一个许多表实体,而不适用于后续操作。