C# 使用带有SQLite数据库的nHibernate进行非常缓慢的更新

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

我正在使用nHibernate,每个方法有一个会话。我使用Castle Dynamic Proxy在执行该方法之前打开一个会话和一个事务,并在执行该方法之后提交事务并关闭会话

我使用的是SQLite数据库,如果将cascade设置为SaveUpdate或None,则不会改变任何内容。nHIbernate使用默认配置的Fluent nHIbernate进行配置

刷新会话时,需要2秒以上的时间

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();
}