2017-07-07 69 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