从NHibernate调用存储过程并检索@@ ROWCOUNT

时间:2016-04-05 12:37:41

标签: c# sql-server stored-procedures nhibernate

在尝试了几个小时之后,我开始认为如果没有你的帮助我无法解决这个问题。情况:

我在SQL Server Management Studio中的存储过程(基本上):

SET NOCOUNT ON;
DELETE myTable
...                    -- Complex join query that deletes duplicates
RETURN @@ROWCOUNT      -- The number of rows affected

此过程运行良好,如果我在SSMS中运行它,则运行以下查询:

USE myDb
GO
DECLARE @return_value int
EXEC    @return_value = [dbo].[StoredProcedure]
        @var1 = N'asd',
        @var2 = N'fgh',
        @var3 = N'jkl'
SELECT  'Return Value' = @return_value
GO

结果显示为1行,名称为Return Value,值为8700(这是正确,它是由删除的行数查询)。

我的问题始于我的C#/ NHibernate代码。在我的NHibernate映射中:

<sql-query name="MyStoredProcedureName">
  exec dbo.StoredProcedure @var1=:var1, @var2=:var2, @var3=:var3
</sql-query>

在我调用存储过程的方法中:

var deletedEntities = session.GetNamedQuery("MyStoredProcedureName")
                             .SetString("var1", "asd")
                             .SetString("var2", "fgh")
                             .SetString("var3", "jkl")
                             .ExecuteUpdate();

这导致deletedEntities = -1。我希望它是deletedEntities = 8700

我想指出以下确实会返回受影响的行数:

var deletedEntities = session.CreateQuery("DELETE Class c WHERE c.var1 = :var1 AND c.var2 = :var2 AND c.var3 = :var3")
                             .SetString("var1", var1)
                             .SetString("var2", var2)
                             .SetString("var3", var3)
                             .ExecuteUpdate();

其中Class是属于NHibernate映射的类。

所以,总结一下:

  1. SIMPLE session.CreateQuery上的ExecuteUpdate让我回复受影响的行数(GOOD)
  2. COMPLEX session.GetNamedQuery上的ExecuteUpdate让我回归-1(BAD)
  3. 当我在SSMS(GOOD)中执行时,这个相同的复杂存储过程会让我回到所需的8700
  4. 任何人都知道如何解决2?

1 个答案:

答案 0 :(得分:1)

使用http://csharptechies.blogspot.co.uk/2013/04/how-to-get-return-value-from-stored.html我的代码正常运行。在此过程中,将RETURN @@ROWCOUNT替换为SELECT @@ROWCOUNT

在C#代码中,我将.ExecuteUpdate()替换为.UniqueResult()。 UniqueResult返回一个对象,该对象将包含@@ROWCOUNT值(需要转换为int,如上面链接中所述)。

所以解决方案是一个组合(我想使用映射):

  1. 使用SELECT代替RETURN
  2. 使用。UniqueResult()代替.ExecuteUpdate()
  3. 编辑:我遇到了另一个问题,只要有大量要删除的记录,查询就会超时。我在其他问题的帮助下解决了这个问题,例如SQL Server: Effects of using 'WITH RECOMPILE' in proc definition?

    1. 在大型表格的复杂查询中使用WITH RECOMPILE(我的查询涉及left outer joinmin(id)group by,受影响的记录数通常是大约20.000但可以运行到100.000+并且我的表中有超过350.000.000个记录)以避免超时。