NHibernate在每次INSERT之前执行SELECT

时间:2013-11-08 22:28:35

标签: c# sql nhibernate

我有一个只有一个字段(Value)的实体和以下映射:

Id(x => x.Value).Column("value").Length(150);

当我执行以下代码时

using (var tx = Database.BeginTransaction())
{
    for (int i = 0; i < 10; i++)
    {
        var e = new Entity { Id = "Value" + i };
        Database.Entities.Add(e);
    }
    tx.Commit();
}

NHibernate在每次SELECT调用之前执行INSERT语句。像这样:

NHibernate: SELECT * FROM entity entity_ WHERE entity_.value=@p0; @p0 = 'Value0'
NHibernate: INSERT INTO entity ...
NHibernate: SELECT * FROM entity entity_ WHERE entity_.value=@p0; @p0 = 'Value1'
NHibernate: INSERT INTO entity ...
NHibernate: SELECT * FROM entity entity_ WHERE entity_.value=@p0; @p0 = 'Value2'
NHibernate: INSERT INTO entity ...

如果我启用批量模式(设置adonet.batch_size),则会首先执行所有SELECT语句,然后以批量模式执行INSERT语句。

这是预期的行为吗?如果是这样,我该怎么做才能避免这种情况?

1 个答案:

答案 0 :(得分:2)

这种行为是正确的,与这些事实有关:

  1. ID beeing string - &gt;生成器类型已分配(问题中的流畅映射行)
  2. 虽然气馁但使用了session.SaveOrUpdate(e)
  3. 请参阅:5.1.4.7. Assigned Identifiers,摘录:

      

    由于其固有的性质,使用此生成器的实体不可能   通过ISession的SaveOrUpdate()方法保存。相反,你必须   如果要保存对象,则明确指定NHibernate   通过调用的Save()或Update()方法更新   的ISession。

    在这种情况下,NHibernate几乎绝望了。为什么?因为没有办法确保分配的id('value1','value2'..)已经在DB中了。因此,为了确保是否应该发出 INSERT UPDATE ,它必须询问数据库。这就是选择之前SELECT的原因。

    仅在Save(e)后面使用Database.Entities.Add(e),并且不会发出支持基础结构 SELECT。