2017-07-07 2 views
0

Ich habe eine Funktion in C#, die Daten einfügen soll. Alles, was es tun soll, ist eine gespeicherte Prozedur aufzurufen, die von einem Request Body gegeben wird, den ich über Fiddler beliefert. Im Moment versuche ich es zu testen, aber ich bekomme diesen Fehler immer wieder.SQLCommand in C# Nicht liefernder Parameter

"Prozedur oder Funktion 'spCreatePerson' erwartet den Parameter '@first', der nicht mitgeliefert wurde." Hier

ist die objekt-

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; } 
} 

Hier wird die Anfrage Körper -

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

Hier ist die Funktion für den Aufruf des 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; 
    } 

Wie Sie ich sehen kann übergeben im Parameter, aber bekomme diesen Fehler. Gibt es etwas, das ich im Code verpasst habe? Ich bin hindurchgegangen und die Daten scheinen gut zu bestehen.

EDIT

Hier ist die gespeicherte prozedur

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

Beim Debuggen, wird 'p.FirstName' einen Wert enthalten? – David

+0

@David Ja. "Test" wird vom Anfragetext übernommen. Ich debuggte alles, was die Daten durchzumachen scheinen. –

+0

Können Sie der Frage hier ein gespeichertes proc-Skript hinzufügen? – Sujith

Antwort

0

Diese könnte die Ursache sein, aber zumindest ist dies eine Variable in der gesamten Gleichung zu beseitigen. Diese Zeilen sind sehr suspekt: ​​

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

Zum einen negiert die zweite Zeile die erste vollständig. Sie sollten vertauscht werden:

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

Aber mehr auf den Punkt, sie veranschaulichen ein viel größeres potenzielles Problem. Nämlich ...

Wo sind cmd und con selbst deklariert und erstellt?

Wenn Sie Verbindungs- und Befehlsobjekte verwenden, die in einem größeren Bereich vorhanden sind, können Sie sie möglicherweise für andere Vorgänge freigeben. Dies ist eine schlechte Sache und kann zu sehr schwer zu diagnostizierenden Fehlern führen.

Als allgemeine Faustregel sollte man Befehle und Verbindungen in einem möglichst kleinen Umfang deklarieren, erstellen, verwenden und entsorgen.

Sie gewinnen nichts, indem Sie sie herum, das zugrunde liegende System ist ziemlich gut optimiert. Aber was Sie tun, ist die Möglichkeit von Fehlern und merkwürdigem Verhalten im Code.

Die Struktur sollte grundsätzlich (in etwas-Pseudo-Code):

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

Sie waren globale Variablen in meiner DBHelper-Klasse. –

+0

@KrazyDev: Eine ironisch benannte Klasse :) Zu sehen, dass diese Methode auch "statisch" ist, ist ein anderes potentielles Problem. Vielleicht möchten Sie sich etwas wie das Repository-Muster ansehen (was mit Entity Framework einfach zu implementieren ist). Oder zumindest Serviceklassen, die wie Repositories funktionieren. Grundsätzlich bleiben Sie bei objektorientiertem Code. "Globale" Dinge und "machen alles statisch" ist ein rutschiger Abhang zu einer dunklen Welt von Buggy-Code. – David

Verwandte Themen