C# 使用带有SQLite数据库的nHibernate进行非常缓慢的更新
我正在使用nHibernate,每个方法有一个会话。我使用Castle Dynamic Proxy在执行该方法之前打开一个会话和一个事务,并在执行该方法之后提交事务并关闭会话 我使用的是SQLite数据库,如果将cascade设置为SaveUpdate或None,则不会改变任何内容。nHIbernate使用默认配置的Fluent nHIbernate进行配置 刷新会话时,需要2秒以上的时间C# 使用带有SQLite数据库的nHibernate进行非常缓慢的更新,c#,nhibernate,C#,Nhibernate,我正在使用nHibernate,每个方法有一个会话。我使用Castle Dynamic Proxy在执行该方法之前打开一个会话和一个事务,并在执行该方法之后提交事务并关闭会话 我使用的是SQLite数据库,如果将cascade设置为SaveUpdate或None,则不会改变任何内容。nHIbernate使用默认配置的Fluent nHIbernate进行配置 刷新会话时,需要2秒以上的时间 public void AddNewChild(LightPatientDto patient, Ligh
public void AddNewChild(LightPatientDto patient, LightPatientDto child)
{
var ePatient = this.Session.Load<Patient>(patient.Id);
var eChild = this.Session.Load<Patient>(child.Id);
switch (ePatient.Gender)
{
case Gender.Male:
eChild.Father = ePatient;
break;
case Gender.Female:
eChild.Mother = ePatient;
break;
default:
Assert.FailOnEnumeration(eChild.Gender);
break;
}
this.Session.Update(eChild);
this.Session.Flush(); // <== takes more than 2 seconds
}
如何优化执行时间
编辑1
正如@csanchez所建议的,我已经成功地为我的实体添加了动态更新。现在,当我在NH Profiler中查看SQL时,我得到了以下信息:
UPDATE Patient
SET Father_id = 2 /* @p0 */
WHERE Person_id = 21 /* @p1 */
这是一个非常优化!但是,执行时间是。。。1852奥尤女士
在调试器中,我看到它正在提交需要时间的事务。。。我不知道为什么它这么慢
编辑2
每个患者都有医学图片,这些图片以字节数组的形式存储在表中。下面是创建表的SQL(由Fluent nHibernate完成)
如果我用DELETE Picture
删除数据并重新启动应用程序,更新速度会很快
这似乎是nHibernate试图变得聪明,并做一些事情,减缓一切。但是,如果我使用此代码执行纯SQL查询,更新仍然需要一秒钟以上的时间:
using (var tx = this.Session.BeginTransaction())
{
var sql = "UPDATE Patient SET Father_id = 2 WHERE Person_id = 21";
var query = this.Session.CreateSQLQuery(sql);
query.ExecuteUpdate();
tx.Commit();
}
仅在第一次提交到DB时,性能就受到了影响。SQLite可能有一些启动时间 您说的是“每个方法的会话”,但看起来您使用的是模块级会话变量。对会话实例执行的操作越多,缓存导致的速度就越慢。如果这将是一个批处理操作,请考虑StalelEsScript。
还要检查NHibernate+Log4Net的日志记录配置。日志记录越详细,NH的响应速度越慢 不应在每次更改数据时刷新会话。您应该让NHibernate缓冲区更新并刷新批量更改。否则,他们会进行flush隐式操作,而您也不会为此担心。如果您只更新患者的父母或母亲,则可以在患者的映射文件中使用
dynamic update=“true”
。如果我删除flush(),然后提交事务需要2秒钟。Hibernate日志只记录从警告到致命的事件。正如我所说,动态代理打开一个会话,调用该方法并最终关闭会话。每次调用该方法时,这个简单的更新需要2秒钟。
CREATE TABLE Picture (
Id integer PRIMARY KEY AUTOINCREMENT,
Bitmap blob,
Creation datetime,
LastUpdate datetime,
Notes text,
IsImported bool,
Tag_id bigint,
Patient_id bigint,
ThumbnailBitmap blob,
/* Foreign keys */
FOREIGN KEY (Patient_id)
REFERENCES Patient(),
FOREIGN KEY (Tag_id)
REFERENCES "Tag"()
);
using (var tx = this.Session.BeginTransaction())
{
var sql = "UPDATE Patient SET Father_id = 2 WHERE Person_id = 21";
var query = this.Session.CreateSQLQuery(sql);
query.ExecuteUpdate();
tx.Commit();
}