2013-02-06 37 views
4

这是我的代码部分:小巧玲珑输出参数没有返回值

CResponseVO objCResponseVO = new CResponseVO(); 

try 
{ 
    var parameters = new DynamicParameters(); 
    parameters.Add("@UserId", currentUser.userId, DbType.Int32); 
    parameters.Add("@Operation", operation, DbType.String); 
    parameters.Add("@Output", dbType: DbType.Int32, direction: ParameterDirection.Output); 

    using (var connection = SqlAccessHelper.SqlHelper.GetOpenConnection(SqlConnectionHelper.SqlConnectionString())) 
    { 
    var reader = connection.QueryMultiple("USP_DataExtract", parameters, (SqlTransaction)null, 1000000, CommandType.StoredProcedure); 
    int result = parameters.Get<int>("@Output"); 
    if (operation != "insert") 
    { 
     ObservableCollection<DataExtraction.DataExtractionTracker> DataExtractionTracker = new ObservableCollection<DataExtraction.DataExtractionTracker>(reader.Read<DataExtraction.DataExtractionTracker>()); 
     objCResponseVO.addObject("ExtractionStatus", DataExtractionTracker); 
    } 

    objResponseVO.Result = result; 
} 

这是我的SP,我已经基于输出中的参数值使用trycatch提交或回滚:

@UserID int=0, 
@Operation varchar(50)= NULL, 
@Output INT OUTPUT 

AS 
BEGIN 
    BEGIN TRY 
    BEGIN TRANSACTION 
     If(@Operation = 'select') 
     BEGIN 
     SELECT RequestId, UserId, RequestTime, Status,DownloadPath from DataExtractTracker where UserId= @UserID 
     END 

     If(@Operation = 'insert') 
     BEGIN 
     Insert into DataExtractTracker(UserId, RequestTime, Status) values (@UserID, GETDATE(), 'Waiting') 
     END 
     SET @Output = 0 
    COMMIT TRANSACTION 
    END TRY 
    BEGIN CATCH 
    ROLLBACK TRANSACTION 
    SET @Output = 1 
    DECLARE @ErrorMessage NVARCHAR(4000); 
    DECLARE @ErrorSeverity INT; 
    DECLARE @ErrorState INT; 
    SELECT @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE(); 

    -- Use RAISERROR inside the CATCH block to return 
    -- error information about the original error that 
    -- caused execution to jump to the CATCH block. 
    RAISERROR (@ErrorMessage, -- Message text. 
       @ErrorSeverity, -- Severity. 
       @ErrorState -- State.); 
    END CATCH 
END 

但是,我无法检索输出参数值。执行时,我得到一个异常:

int result = parameters.Get<int>("@Output"); 

异常说是这样的:不设置到对象的实例

对象引用。

回答

9

这只是TDS的一个功能,您将得到与ADO.NET相同的功能;返回的参数值通常在TDS流的末尾处为;因此,更新后的值在您完成数据使用之后才可用。

基本上,你需要查询的参数值后,您与reader结束,因为直到那时的价值还没有回来。例如,以下匆忙增加的集成测试通过:

public void TestOutputParameter() 
{ 
    connection.Execute(@" 
create proC#TestOutputParameterProc @Foo int, @Bar int out as 
set @Bar = @Foo select 1 as [A] select 2 as [B]"); 
    try 
    { 
     var args = new DynamicParameters(new { Foo = 123 }); 
     args.Add("@Bar", dbType: DbType.Int32, 
           direction: ParameterDirection.Output); 
     using (var grids = connection.QueryMultiple("#TestOutputParameterProc", 
        args, commandType: CommandType.StoredProcedure)) 
     { 
      // this will fail here; we have not consumed the TDS data yet! 
      // args.Get<int>("@Bar").IsEqualTo(123); 

      // note we don't *have* to read the data here; disposing "grids" 
      // would be enough to skip to the end of the TDS 
      grids.Read<int>().Single().IsEqualTo(1); // A 
      grids.Read<int>().Single().IsEqualTo(2); // B 
     } 
     // at this point we have consumed the TDS data, so the parameter 
     // values have come back to the caller 
     args.Get<int>("@Bar").IsEqualTo(123); 
    } 
    finally 
    { // clean up the proc 
     connection.Execute("drop proC#TestOutputParameterProc"); 
    } 
}