【问题标题】:Insert row into database table using NHibernate without calling scope_identity after the row has been inserted插入行后使用 NHibernate 将行插入数据库表而不调用 scope_identity
【发布时间】:2014-07-01 16:22:25
【问题描述】:

我正在尝试使用 NHibernate 将大量数据插入数据库,但这样做非常慢。我已经阅读了它,到处都建议让 NH 设置行的标识,以便它可以批处理并且不需要在插入后调用 SCOPE_IDENTITY,但是,它是一个带有旧数据库的棕地应用程序,所以我可以t 让 NHibernate 控制行的标识。

有什么方法可以告诉 NH 不选择范围标识而只将行插入数据库?我现在不需要它知道他们的身份,所以插入后行是否知道他们的身份没有什么区别,但我猜我不能告诉 Nhibernate 不要在这种情况?

如果有任何后果,请使用 Fluent NH。

提前致谢。

【问题讨论】:

  • 这真的是个问题吗? SCOPE_IDENTITY 应该是一个会话属性,不需要执行任何数据库操作,例如写入数据和更新表索引 - 它可能需要额外的数据库往返,但就是这样,与所有其他操作相比,它应该相对便宜。为什么这会显着降低插入速度?
  • @rup 是的,它非常相关。 db 生成的密钥会阻止 nhibernate 使用批处理功能。最后,问题不是 scope_identity 本身,而是在每个单独的插入使批量插入速度不可接受之后需要 scope_identity
  • @Eddy 基本上就是这样。这是在将 NHibernate 设置为 SQL 命令之前的最后一次绝望尝试。
  • @Eddy "db 生成的密钥阻止 nhibernate 使用批处理功能。"但是您可以从多次插入中一次性返回所有 ID,不是吗?例如insert into person(name) output inserted.id values('Alice'),('Bob'),('Charlie');
  • 你的目标数据库是什么?您是否使用类似 Repository 来管理映射类型的会话和连接?如果 mssql 并且是:我在我的存储库中添加了一个 BulkInsert,它根据映射类型的属性创建一个数据表,复制行并使用 SqlBulkCopy 进行插入。它并不完美,但速度很快。

标签: c# nhibernate fluent-nhibernate


【解决方案1】:

NH 需要身份来管理缓存中的实体以识别它们。所以我认为没有办法。

您的性能问题不一定是由身份引起的。可能是您刷新会话太多次。尝试关闭自动刷新来验证它或使用 StatelessSession。

ORM 在大规模操作中不是很好。您应该考虑使用更底层的东西(如 SQL)。

【讨论】:

  • 我正在使用一个无状态会话,该会话正在为这个查询创建和处置,并尝试将 20K+ 记录插入数据库。因为身份是由数据库生成的,所以查询中没有发生批处理,所以我得到了 20K+ 个单独的插入和范围身份语句,这意味着插入非常慢。我知道这违反了 NH 的所有原则,但由于我必须尝试使用​​它,我想知道是否有人知道我可以使用的一些巫术。我意识到这是一个远射。
猜你喜欢
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-26
相关资源
最近更新 更多