我正在尝试使用NHibernate进行批量更新,但它没有进行批量更新,它为所有行执行单独写入。我必须写大约10k行到db。
using (var session = GetSessionFactory().OpenStatelessSession())
{
session.SetBatchSize(100);
using (var tx = session.BeginTransaction())
{
foreach (var pincode in list)
{
session.Update(pincode);
}
tx.Commit();
}
}
我尝试使用session.SetBatchSize(100);
将批量大小设置为100,但这没有帮助。还尝试使用cfg.SetProperty("adonet.batch_size", "100");
设置批量大小,但这也没有帮助。
我正在使用GUID主键,因此我不理解批量更新失败的原因。这正是解释here的解决方案。但它不适合我。
注意我在所有实体上映射了乐观并发的版本字段。这可能是没有批量更新的罪魁祸首吗?
修改
我尝试使用状态丰富的会话,但也没有帮助
//example 2
using (var session = GetSessionFactory().OpenSession())
{
session.SetBatchSize(100);
session.FlushMode = FlushMode.Commit;
foreach (var pincode in list)
{
session.Update(pincode);
}
session.Flush();
}
//example 3
using (var session = GetSessionFactory().OpenSession())
{
session.SetBatchSize(100);
using (var tx = session.BeginTransaction())
{
foreach (var pincode in list)
{
session.Update(pincode);
}
tx.Commit();
}
}
example 2
由于某种原因导致双次往返。
修改
进一步研究后我发现,每个session.Update实际上都在更新db using (var session = SessionManager.GetStatelessSession())
{
session.SetBatchSize(100);
foreach (var record in list)
{
session.Update(record);
}
}
我该怎样避免这种情况。
修改
尝试使用刷新模式,但那也没有帮助
using (var session = SessionManager.GetNewSession())
{
session.FlushMode = FlushMode.Never;
session.SetBatchSize(100);
session.BeginTransaction();
foreach (var pincode in list)
{
session.SaveOrUpdate(pincode);
}
session.Flush();
session.Transaction.Commit();
}
编辑4
即使低于一个也无法正常工作,因为我正在获取同一会话中的所有实体并仅在该会话中更新并保存它们...
using (var session = SessionManager.GetSessionFactory().OpenSession())
{
session.SetBatchSize(100);
session.FlushMode = FlushMode.Commit;
session.Transaction.Begin();
var list = session.QueryOver<Pincode>().Take(1000).List();
list.ForEach(x => x.Area = "Abcd" + DateTime.Now.ToString("HHmmssfff"));
foreach (var pincode in list) session.SaveOrUpdate(pincode);
session.Flush();
session.Transaction.Commit();
}
答案 0 :(得分:2)
您正在使用无状态会话。由于无状态会话没有状态,因此以后无法记住任何事情。因此,更新立即执行。
答案 1 :(得分:2)
nhibernate 不批量版本化实体这就是我的问题。
您无法批量处理版本实体,唯一要做的就是使实体不进行版本控制。
答案 2 :(得分:1)
请注意:
附加说明:
在会话中有很多对象时,不要忘记关注刷新和刷新时间。有时刷新比更新更耗时。在提交之前,当您调用flush和查询之前,NH会刷新,除非您将其关闭或使用无状态会话。确保只冲洗一次。