Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么NHibernate拒绝批量插入?_Nhibernate_Sql Server 2008_Bulkinsert_Batching - Fatal编程技术网

为什么NHibernate拒绝批量插入?

为什么NHibernate拒绝批量插入?,nhibernate,sql-server-2008,bulkinsert,batching,Nhibernate,Sql Server 2008,Bulkinsert,Batching,针对SQL Server 2008使用NHibernate 2.1.2.4000。目标表没有触发器或无关索引。这很简单: create table LogEntries ( Id INT IDENTITY NOT NULL, HostName NVARCHAR(32) not null, UserName NVARCHAR(64) not null, LogName NVARCHAR(512) not null, Timestamp DATETIME not nu

针对SQL Server 2008使用NHibernate 2.1.2.4000。目标表没有触发器或无关索引。这很简单:

create table LogEntries (
    Id INT IDENTITY NOT NULL,
   HostName NVARCHAR(32) not null,
   UserName NVARCHAR(64) not null,
   LogName NVARCHAR(512) not null,
   Timestamp DATETIME not null,
   Level INT not null,
   Thread NVARCHAR(64) not null,
   Message NVARCHAR(MAX) not null,
   primary key (Id)
)
我的实体映射是:

<class name="LogEntry" table="LogEntries">
    <id name="Id" unsaved-value="0">
        <generator class="native"/>
    </id>
    <property name="HostName" length="32" not-null="true"/>
    <property name="UserName" length="64" not-null="true"/>
    <property name="LogName" length="512" not-null="true"/>
    <property name="Timestamp" type="utcdatetime" not-null="true"/>
    <property name="Level" not-null="true"/>
    <property name="Thread" length="64" not-null="true"/>
    <property name="Message">
        <column name="Message" sql-type="NVARCHAR(MAX)" not-null="true"/>
    </property>
</class>
作为比较,您将看到我还实现了一个基于BCP的解决方案。以下是一些示例输出:

Saving 10000 items with batch size 500: 00:00:00.3142613
Saving 10000 items with batch size 100: 00:00:00.6757417
Saving 10000 items with batch size 1: 00:00:26.2509605
显然,BCP解决方案比NH解决方案快数英里。同样明显的是,配料会影响BCP溶液的速度,但不会影响NH溶液的速度。使用NHibernate进行插入时,NHProf显示以下内容:

只有
INSERT
s,没有
SELECT
s。有趣的是,NHProf在任何时候都没有告诉我

根据上面的测试用例,我尝试在配置文件和代码中指定
adonet.batch_size

现在,我不期望NH溶液达到BCP溶液的速度,但我至少想知道为什么批处理不起作用。如果启用批处理就足够了,那么我可以在BCP上使用NH解决方案来简化代码库

有人能解释为什么NH拒绝接受ADO.NET批处理,以及我能做些什么来修复它吗?我读过的所有分散的NH“文档”都说明,您需要做的就是指定
adonet.batch_size
,并(最好)使用无状态会话,但我正在做这两件事


感谢使用
identity
中断批处理

由法比奥·莫洛解释


最好的选择是切换到另一个生成器(我始终建议使用
hilo
guid.comb

如果您使用标识作为主键,则无论是
ISession
还是
IStatelessSession
都无法批量插入


插入时,Nhibernate将在Id属性中输入正确的值。但是当您使用Identity时,唯一可以使用此Id的地方是数据库。用于批量插入。

@Kent:你有没有看过NHProf在引擎盖下发生的事情?您确定insert操作没有被批处理吗?是的,我已经用NHProf查看过了,在使用批处理和不使用批处理时没有区别。所以语句没有被分组到批处理中?一些想法:1)你能发布你的完整配置文件吗?2) 您是否尝试过直接在Nhibernate配置文件中指定Nhibernate批处理大小,而不是在测试夹具中重写它?此外,您的主键是否映射为本机?在每次插入操作后,是否看到每个新id的select语句?我想知道这是否是没有发生批处理的原因?@DanP:我更新了我的帖子来回答你的所有问题。谢谢Diego,但是Fabio的帖子只谈到使用
ISession
,而不是
ISTATelesSession
。根据我的问题,我使用的是后者。无需执行后续的
选择
来获取ID,也不会发生这种情况。因此,应该可以对
INSERT
s进行批处理。此外,NH文档()第17.6节列出了批处理的限制,并且根本没有提到ID生成器。我知道,与NH的合作伙伴关系——但令人难以置信的沮丧。肯特乐队,我不认为<代码> ISTATELELSISS/<代码>支持批处理。您是否尝试过使用常规的
会话
?在某些情况下,它的性能更好,即使对于批量场景也是如此。确实如此,但我不怪你不确定。我认为问题的关键是NH文档的糟糕状态。似乎即使使用无状态会话,NH仍然坚持更新实体ID,这排除了批处理。我找不到引文,尤其是在NH文档中,但我把你的作为答案。顺便说一句,我想指出,我错误地说,
SELECT
没有发生,以防不明显。+1这是普遍共识,但我希望引文。对我来说,使用无状态会话应该足以放弃更新实体ID。否则,一种表示我对实体ID不感兴趣的方法将非常有用,因为这样可以实现批处理。也许这是一个错误的工作工具的情况,但我希望至少尝试它。
Saving 10000 items with batch size 500: 00:00:12.3064936
Saving 10000 items with batch size 100: 00:00:12.3600981
Saving 10000 items with batch size 1: 00:00:12.8102670
Saving 10000 items with batch size 500: 00:00:00.3142613
Saving 10000 items with batch size 100: 00:00:00.6757417
Saving 10000 items with batch size 1: 00:00:26.2509605