在NHibernate映射代码的SqlInsert上使用自定义函数时出错

时间:2013-05-19 11:30:28

标签: postgresql nhibernate mapping-by-code

我有一个NHibernate映射代码,如果在标准SqlInsert上使用标准INSERT

class ProductTranslationMapping : ClassMapping<ProductTranslation>
{
    public ProductTranslationMapping ()
    {
        .
        .
        SqlInsert ("insert into product_translation(product_id, language_code, product_name, product_description) values(?,?,?,?)");

        .
        .       
    }
}

但是,我想使用Postgresql存储过程,因此插入和更新都可以使用相同的例程

class ProductTranslationMapping : ClassMapping<ProductTranslation>
{
    public ProductTranslationMapping ()
    {

        .       
        .
        SqlInsert ("select merge_product_translation(?,?,?,?)");
        SqlUpdate ("select merge_product_translation(?,?,?,?)");
        .
        .       
    }
}

但是当我使用Postgresql函数时,它有一个错误:

Unhandled Exception:
NHibernate.StaleStateException: Unexpected row count: -1; expected: 1
  at NHibernate.AdoNet.Expectations+BasicExpectation.VerifyOutcomeNonBatched (Int32 rowCount, IDbCommand statement) [0x00000] in <filename unknown>:0 
  at NHibernate.AdoNet.NonBatchingBatcher.AddToBatch (IExpectation expectation) [0x00000] in <filename unknown>:0 
  at NHibernate.Persister.Entity.AbstractEntityPersister.Insert (System.Object id, System.Object[] fields, System.Boolean[] notNull, Int32 j, NHibernate.SqlCommand.SqlCommandInfo sql, System.Object obj, ISessionImplementor session) [0x00000] in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: NHibernate.StaleStateException: Unexpected row count: -1; expected: 1
  at NHibernate.AdoNet.Expectations+BasicExpectation.VerifyOutcomeNonBatched (Int32 rowCount, IDbCommand statement) [0x00000] in <filename unknown>:0 
  at NHibernate.AdoNet.NonBatchingBatcher.AddToBatch (IExpectation expectation) [0x00000] in <filename unknown>:0 
  at NHibernate.Persister.Entity.AbstractEntityPersister.Insert (System.Object id, System.Object[] fields, System.Boolean[] notNull, Int32 j, NHibernate.SqlCommand.SqlCommandInfo sql, System.Object obj, ISessionImplementor session) [0x00000] in <filename unknown>:0 

如果有帮助,这是我的Postgresql存储过程:

create or replace function merge_product_translation(p_product_id int, p_language_code text, p_product_name text, p_product_description text) returns int
as
$$
begin
    if not exists(select * from product_translation where product_id = p_product_id and language_code = p_language_code) then       
        insert into product_translation(product_id, language_code, product_name, product_description)
        values(p_product_id, p_language_code, p_product_name, p_product_description);
    else        
        update product_translation set
            product_name = p_product_name,
            product_description = p_product_description
        where product_id = p_product_id and language_code = p_language_code;    
    end if;

    return 1;

end;
$$
language 'plpgsql';

我也试过以下,但还是运气不好,所有这些都有错误:

SqlInsert ("perform merge_product_translation(?,?,?,?)");
SqlInsert ("call merge_product_translation(?,?,?,?)");  
SqlInsert ("{call merge_product_translation(?,?,?,?)}");        

我应该使用什么,以便我可以避免错误unexpected row count of -1?它也很难谷歌,因为谷歌消除了-1

1 个答案:

答案 0 :(得分:1)

NHibernate需要检查其内部生成的SQL命令的结果。您的自定义实现(存储过程)需要/应用相同的内容,因为它的处理方式相同。

但是有很好的解决方案。在此处阅读更多17.3. Custom SQL for create, update and delete

摘录:

  

默认情况下,存储过程必须影响存储过程   NHibernate生成的SQL会有多少行。 NHibernate使用   IDbCommand.ExecuteNonQuery检索受影响的行数。   可以使用check =“none”属性禁用此检查   sql-insert元素。

解决方案:...按照以下方式调整您的映射:

<sql-insert check="none" >..</sql-insert>
<sql-update check="none" >..</sql-update>