2017-07-07 72 views
0

我在c#中有一個功能是插入數據。它應該做的就是調用從我通過Fiddler提供的Request Body中給出的存儲過程。現在我試圖測試它,但我一直得到這個錯誤。SQLCommand在C#不提供參數

「過程或函數'spCreatePerson'需要參數'@first',它沒有提供。」

這裏是對象 -

public class Person 
{ 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public string Phone { get; set; } 

    public string Email { get; set; } 

    public int PersonTypeId { get; set; } 
} 

這裏是請求主體 -

{"FirstName":"Test","LastName":"MuhFuh","Phone":"5555555555","Email":"[email protected]","PersonTypeId":1} 

下面是函數調用的PROC-

public static int InsertData(string procName, Person p) 
    { 
     int rowsAffected = 0; 

     con = CreateConnection(); 

     using (con) 
     { 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd = new SqlCommand("spCreatePerson", con); 

      cmd.Parameters.AddWithValue("@first", p.FirstName); 
      cmd.Parameters.AddWithValue("@last", p.LastName); 
      cmd.Parameters.AddWithValue("@email", p.Email); 
      cmd.Parameters.AddWithValue("@phone", p.Phone); 
      cmd.Parameters.AddWithValue("@pTypeID", p.PersonTypeId); 

      rowsAffected = cmd.ExecuteNonQuery(); 
     } 

     return rowsAffected; 
    } 

正如你可以看到我傳入參數,但得到這個錯誤。有沒有我在代碼中錯過的東西?我通過它,數據似乎傳遞得很好。

編輯

這裏是存儲程序 -

CREATE PROC [dbo].[spCreatePerson] @first nvarchar(100), @last 
nvarchar(100), @email nvarchar(50), @phone nvarchar(100), @pTypeID int 

AS 

INSERT INTO Person(FirstName, LastName, Email, Phone, PersonTypeID) 
VALUES(@first, @last, @email, @phone, @pTypeID) 


GO 
+1

調試時,不'p.FirstName'包含值? – David

+0

@David是的。正在從請求主體傳入「測試」。我調試了所有的數據似乎正在經歷。 –

+0

你可以在這裏添加存儲的proc腳本到這個問題嗎? – Sujith

回答

0

可能是罪魁禍首,但起碼這是整個公式的變量來消除。這些線是非常可疑的:

cmd.CommandType = CommandType.StoredProcedure; 
cmd = new SqlCommand("spCreatePerson", con); 

首先,第二行是完全否定第一行。他們應該交換:

cmd = new SqlCommand("spCreatePerson", con); 
cmd.CommandType = CommandType.StoredProcedure; 

但更重要的是,他們說明了一個更大的潛在問題。即...

哪裏有cmdcon甚至聲明和創建?

如果您使用的連接和命令對象存在於更大範圍內,那麼您可能會將它們與其他操作共享。這是一件壞事,可能導致很難診斷錯誤。

作爲一般的經驗法則,我們應該在儘可能小的範圍內聲明,創建,使用和處置命令和連接。

你沒有得到任何東西,保持身邊,基本系統是很好優化。但是你正在做的是在代碼中打開bug和奇怪行爲的可能性。

結構應基本上是(在一定程度上僞代碼):

using (var con = new Connection()) 
using (var cmd = new Command(con)) 
    // set parameters, command type, etc. 
    // execute the command, get any results you might need 
} 
// any follow-up logic, etc. 
+0

他們是我DBHelper類中的全局變量。 –

+0

@KrazyDev:一個具有諷刺意味的類:)看到這種方法也是'靜態'是另一個潛在的問題。你可能想看看類似於存儲庫模式的東西(這對於使用實體框架來實現是微不足道的)。或者至少是像倉庫那樣的服務類。基本上,堅持面向對象的代碼。 「全球化」的事物和「讓所有事物保持靜止」對於一個黑暗的車輛代碼世界來說是一個滑坡。 – David