2011-05-04 64 views
13

使用功能的進口這裏是我的SQL Server存儲過程:我不能得到的輸出參數時,由實體框架

ALTER PROCEDURE [dbo].[SearchUser] 
    (@Text NVARCHAR(100), 
    @TotalRows INT = 0 OUTPUT) 
AS 
BEGIN 
    SELECT @TotalRows=1000 
    SELECT * from Users 
END 

而且我的C#代碼

using (var context = new TestDBEntities()) 
{ 
    var outputParameter = new ObjectParameter("TotalRows", typeof(Int32)); 
    context.SearchUser("", outputParameter); 
    Response.Write(outputParameter.Value); 
} 

然而outputParameter.Value始終是空的。

有人能告訴我爲什麼嗎?

+0

我們需要看到TestDBEntities。此外,您需要將outputParameter作爲out來獲取任何結果。 – 2011-05-04 09:39:44

+0

問題是TestDBEntities無法返回outputParameter,因爲您正在調用它。因此,我需要看看TestDBEntities.SearchUser是如何定義的。否則我無法回答這個問題。 – 2011-05-05 02:36:06

+0

對不起,我不會從奇怪的網站下載。我建議你看看它。 – 2011-05-05 05:14:41

回答

44

輸出參數填寫其實際值durin g執行存儲過程。

但是,表值存儲過程實際上只在您嘗試迭代結果記錄集但不調用包裝器方法時執行。

所以,這個簡化版,工作:

using (var context = new TestDBEntities()) 
{ 
    var outputParameter = new ObjectParameter("TotalRows", typeof(Int32)); 
    context.SearchUser("", outputParameter); 

    // Paremeter value is null, because the stored procedure haven't been executed 
    Response.Write(outputParameter.Value); 

} 

這並不:

using (var context = new TestDBEntities()) 
{ 
    var outputParameter = new ObjectParameter("TotalRows", typeof(Int32)); 

    // Procedure does not executes here, we just receive a reference to the output parameter 
    var results = context.SearchUser("", outputParameter); 

    // Forcing procedure execution 
    results.ToList(); 

    // Parameter has it's actual value 
    Response.Write(outputParameter.Value); 

} 

當你使用存儲過程有什麼不返回任何記錄工作,他們在方法調用後立即執行,因此您在輸出參數中有實際值。

+0

謝謝,這對我有幫助。看來我們必須在讀取輸出參數的值之前將結果放到列表中 – Netricity 2012-03-20 12:27:22

+0

真的很感謝您的幫助,您可以節省我幾個小時的搜索 – 2014-10-09 20:23:44

+0

如果您有一個int返回類型而不是一個列表? – Alao 2015-04-08 19:08:30

0

我以前有同樣的問題。主要原因我認爲,實體框架在用戶存儲過程具有輸出參數並返回結果集的情況下存在缺陷。例如:

ALTER PROCEDURE [dbo].[SearchTest] 
( 
    @RowTotal INT = 0 OUTPUT, 
    @RowCount INT = 0 OUTPUT 
) 
AS 
BEGIN 
    SET NOCOUNT ON 
    SELECT * FROM SomeThing 
    SELECT @RowTotal = 1233, @RowCount = 5343 
END 

但是如果你改變了用戶存儲過程如下,你可以得到的輸出PARAMS

ALTER PROCEDURE [dbo].[SearchTest] 
( 
    @RowTotal INT = 0 OUTPUT, 
    @RowCount INT = 0 OUTPUT 
) 
AS 
BEGIN 
    SET NOCOUNT ON 
    SELECT @RowTotal = 1233, @RowCount = 5343 
END 

可以解決辦法如下:

ALTER PROCEDURE [dbo].[SearchTest] 
AS 
BEGIN 
    DECLARE @RowTotal INT, @RowCount INT 

    SET NOCOUNT ON 
    SELECT @RowTotal = 1233, @RowCount = 5343 

    SELECT @RowTotal AS RowTotal, @RowCount AS RowCount, s.* 
    FROM SomeThing s 

END 

如果有人有更好的解決方案,請告訴我

+0

這似乎不是這種情況了。 – 2012-05-15 19:06:56

+0

我認爲第二個答案是更好的解釋 – Zruty 2012-11-07 22:09:31

1

由於我們的單元測試失敗,所以我們有一個類似的問題。總之,如果你有一個存儲過程不返回任何東西,你需要確保將響應類型設置爲'None'設置爲'None'時,它會在調用時被執行而不被調用。

如果您返回任何東西(如標量字符串類型的結果)當您使用即使.Count之間()或.ToList()是包含函數調用的方法之外的結果將excecute它

因此,儘量不要強制執行,如果不需要的話,在需要時它應該優先執行,但一定要正確聲明它或它可能無法正常工作。

+0

將響應類型設置爲'none'?哪裏?碼? – 2015-08-20 18:27:09

+0

@JamesBailey - 實體框架設計師有一個模型瀏覽器和相關的屬性表。在此屬性表中,您可以將存儲過程實體框架函數導入的導入函數返回類型設置爲none。當然這採用數據庫第一種方法。如果先使用代碼,我不確定如何執行此設置... – barrypicker 2018-03-07 23:11:56