2013-02-06 61 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"); 
    } 
}