NHibernate ISession.Save()-为什么会立即持久化我的实体?
我正在使用NHibernate创建大量实体,将它们附加到ISession,然后使用事务将更改提交到数据库。代码示例如下:NHibernate ISession.Save()-为什么会立即持久化我的实体?,nhibernate,transactions,isession,Nhibernate,Transactions,Isession,我正在使用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 _c
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();
}
ISession\u context=SessionProvider.OpenSession();
//创建新实体
对于(int i=0;i尝试:
使用(会话_context=SessionProvider.OpenSession())
使用(var tx=_context.BeginTransaction())
{
//创建新实体
对于(inti=0;i
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();
}
ISession\u context=SessionProvider.OpenSession();
//保留对数据库的所有更改
使用(var tx=_context.BeginTransaction())
{
//创建新实体
对于(int i=0;i您使用的是哪个标识生成器?如果您使用MSSQL/MySQL的identity
或Oracle的sequence
等插入后生成器来生成Id字段的值,这就是您的问题
发件人:
Post insert生成器,如名称所示
建议,在
实体存储在数据库中
对执行select语句
数据库。它们有很多缺点,
在我看来,它们必须被使用
只在棕地项目上。那些
发电机是我们不建议的
作为NH团队
一些缺点是
跟随
工作单元因使用
那些策略,如果
您正在使用FlushMode。提交,每个
将结果保存在insert语句中
针对DB。作为最佳实践,我们
应将插入延迟到提交,
但是使用插入后生成器
使其在保存时提交(这是什么
UoW不这样做)
这些战略
取消批处理程序,您不能接受
发送多个查询的优点
立即(因为它必须在
保存时间)
您可以在配置中设置批处理大小:
<add key="hibernate.batch_size" value="10" />
或者您可以在代码中进行设置。并确保在事务范围内进行保存。尝试将FlushMode设置为提交:
ISession _context = SessionProvider.OpenSession();
context.FlushMode = FlushMode.Commit;
同行关于设置批量大小的建议也很好
我的理解是,在使用数据库标识列时,NHibernate将推迟插入,直到刷新会话,除非它需要执行插入以检索外键或确保查询返回预期结果。
Rebeliard的答案可能取决于你的地图
您没有使用显式事务(StuffOccurs的回答)
默认的刷新模式是自动的,这会使事情复杂化(JamieIDE的答案)
如果通过任何更改使用nhibernate api进行任何查询,默认行为是首先将缓存刷新到数据库,以便这些查询的结果与会话实体表示相匹配
我认为这实际上可能是问题所在。我目前有:在我的配置文件中设置。今晚我将进行测试,并将其标记为答案,如果这是问题所在。谢谢!我一直在使用标识作为Id生成器,这似乎是我问题的原因。我现在正在寻找工作单元/存储库模式的合适替代方案,在这里我想明确首先将多个实体与ISession关联后,我自己刷新会话。谢谢。这是预期的行为,保存
在事务
之外执行。正确答案应该是@StuffOccessdown@THBBFT,在事务之外不会导致保存发送到数据库。StuffOccess没有给出正确的答案,说明为什么它会在Save
调用中插入。这个答案只是为了确保插入被回滚,但这不是OP关注的问题。它的编辑进一步证实了这一点。尝试将其置于顶部。
ISession _context = SessionProvider.OpenSession();
context.FlushMode = FlushMode.Commit;