NHibernate批量插入不起作用 [英] NHibernate batch insert not working

查看:55
本文介绍了NHibernate批量插入不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试让 NH 批量插入工作以将一些旧数据迁移到我们的新数据库.对于测试样本,我已像这样配置批量大小:

I am trying to get NH batch insert to work to migrate some old data to our new DB. For a test sample I have configured batch size like so:

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

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

and in a stateless session I insert some 1000 objects before committing the transaction. The object id strategy is guid.comb and is mapped as follows:

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

使用 NH Profiler 我可以看到所有对象都作为单独的语句插入并且没有进行批处理,所有对象看起来都像:

Using NH Profiler I can see that all objects are inserted as individual statements and are not batched, all of them pretty much looking like:

INSERT INTO Buddies
       (id)

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

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

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

What might be the reason, what should I do to get batching to work?

推荐答案

DML 操作的批处理适用于无状态会话,但它具有与有状态会话批处理相同的限制,以及一些额外的:

Batching of DML operations works with stateless session, but it has the same limitations than batching with state-full session, and some additional:

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

在您对另一个答案的评论中看到,您的实体跨越许多表.不能批量处理.

Seen in your comment on another answer, your entity span many tables. It cannot be batched.

这是对其工作原理的简化且不完整的解释.DML 批处理器通过使用插入或更新或删除命令及其值的参数来工作.它存储它,连同它的参数值.在它接收到的下一个命令时,它检查它是否与前一个匹配.如果是,则存储其参数值.如果是另一个命令,它会刷新上一个批处理并存储新命令.

Here is a simplified and incomplete explanation of how it works. The DML batcher works by taking an insert or update or delete command, with parameters for its values. It stores it, along with its parameters values. At the next command it receives, it checks if it matches the previous one. If yes, it stores its parameters values. If it is another command, it flushes the previous batch and stores the new command.

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

That is why an entity spanning many table cannot be batched: each operation on it implies many commands, causing the batcher to flush at each operation. In some edge cases where you insert a base non-abstract entity not spanning many table then a descendant entity spanning many tables, you may witness the base table insert from the first descendant entity to be batched with the insert of the base entity. But that is a corner case, not actually worth trying to exploit, since it works only for the first many table entity following a base entity operation, and not for following operations.

这篇关于NHibernate批量插入不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆