我正在使用NHibernate创建大量实体,将它们附加到我的ISession,然后使用事务将我的更改提交到数据库。代码示例如下:
ISession _context = SessionProvider.OpenSession();
//Create new entities
for(int i=0; i<100; i++)
{
MyEntity entity = new MyEntity(i);
//Attach new entity to the context
_context.Save(entity);
}
//Persist all changes to the database
using(var tx = _context.BeginTransaction())
{
//Flush the session
tx.Commit();
}
我的印象是_context.Save()行只是让ISession知道新实体,但是在我通过tx.Commit()行刷新会话之前,没有任何更改持久存储到数据库。 / p>
我观察到的是,每次调用_context.Save()时数据库都会获得一个新实体。因此,我最终会对数据库进行过多的单独调用。
有谁知道为什么ISession.Save()会自动持久更改?我是否误解了NHibernate的行为方式?感谢。
***编辑 - 只是为了澄清(根据两个建议的答案) - 我的问题是,一旦我调用_context.Save(),数据库就会更新。我不指望这会发生。我希望在调用tx.Commit()之前不要将任何内容插入到数据库中。到目前为止,两个建议的答案都没有帮助解决这个问题。
可以找到有关身份生成器的一些有用信息here
答案 0 :(得分:6)
尝试:
using(Session _context = SessionProvider.OpenSession())
using(var tx = _context.BeginTransaction())
{
//Create new entities
for(int i=0; i<100; i++)
{
MyEntity entity = new MyEntity(i);
//Attach new entity to the context
_context.Save(entity);
}
//Flush the session
tx.Commit();
}
答案 1 :(得分:6)
您使用的是哪个身份生成器?如果您使用MSSQL / MySQL的Identity
或Oracle的sequence
之类的插入后生成器来生成Id字段的值,那就是您的问题。
来自NHibernate POID Generators Revealed:
发布插入生成器,作为名称 建议,在之后分配id 实体存储在数据库中。一个 执行select语句 数据库。它们有许多缺点, 在我看来,他们必须被使用 仅限棕地项目。那些 发电机是什么我们不建议 作为NH团队。
一些缺点是 以下
- 工作单位被打破了 那些策略。无论如何 你正在使用FlushMode.Commit 将结果保存在insert语句中 反对DB。作为最佳实践,我们 应该将插入推迟到提交, 但使用后插入生成器 让它在保存时提交(这是什么 UoW不这样做)。
- 那些策略 取消batcher,你不能采取 发送多个查询的优点 立刻(因为它必须到数据库) 保存的时间)
醇>
答案 2 :(得分:2)
您可以在配置中设置批量大小:
<add key="hibernate.batch_size" value="10" />
或者您可以在代码中设置它。并确保在事务范围内进行保存。
答案 3 :(得分:1)
尝试将FlushMode设置为Commit:
ISession _context = SessionProvider.OpenSession();
context.FlushMode = FlushMode.Commit;
同行建议设置批量大小也是好的。
我的理解是,当使用数据库标识列时,NHibernate将推迟插入直到会话被刷新,除非它需要执行插入以检索外键或确保查询返回预期结果。
答案 4 :(得分:0)
怎么样:
ISession _context = SessionProvider.OpenSession();
//Persist all changes to the database
using(var tx = _context.BeginTransaction())
{
//Create new entities
for(int i=0; i<100; i++)
{
MyEntity entity = new MyEntity(i);
//Attach new entity to the context
_context.Save(entity);
}
//Flush the session
tx.Commit();
}
答案 5 :(得分:0)
好吧