In meinem Testprojekt habe ich eine statische Klasse namens FixtureSetup, mit der ich meine Integrationstestdaten für die Validierung einrichten kann.Ist meine SqlCommand-Variable überlastet? Wurde es müde?
Ich benutze dieselbe SqlCommand- und SqlParameter-Variable (nicht das Objekt selbst) innerhalb dieser Klasse, wiederhole immer wieder dieselben Variablenreferenzen und weise jedes Mal neue SqlCommand- und SqlParameter-Objekte zu. Meine Verbindung selbst wird einmal erstellt und an die Methoden übergeben, die das Setup durchführen. Daher verwendet jedes Setup eine eigene eindeutige Verbindungsreferenz, und während dasselbe conn mehrmals verwendet wird, ist es immer in einer linearen Sequenz.
In einer solchen Methode stieß ich auf eine sehr merkwürdige Situation, in der meine SqlCommand-Variable einfach müde geworden zu sein scheint.
cmd = new SqlCommand("INSERT INTO Subscription (User_ID, Name, Active) VALUES (@User_ID, @Name, @Active)", conn);
parameter = new SqlParameter("@User_ID", TestUserID); cmd.Parameters.Add(parameter);
parameter = new SqlParameter("@Name", "TestSubscription"); cmd.Parameters.Add(parameter);
parameter = new SqlParameter("@Active", true); cmd.Parameters.Add(parameter);
cmd.ExecuteNonQuery();
cmd = new SqlCommand("SELECT Subscription_ID FROM [Subscription] WHERE Name = 'TestSubscription'", conn);
parameter = new SqlParameter("@User_ID", TestUserID);
cmd.Parameters.Add(parameter);
using (dr = cmd.ExecuteReader())
{
while (dr.Read())
{
TestSubscriptionID = dr.GetInt32(dr.GetOrdinal("Subscription_ID"));
}
}
cmd = new SqlCommand("INSERT INTO SubscriptionCompany (Subscription_ID, Company_ID) VALUES (@Subscription_ID, @Company_ID)", conn);
parameter = new SqlParameter("@Subscription_ID", TestSubscriptionID); cmd.Parameters.Add(parameter);
parameter = new SqlParameter("@Company_ID", KnownCompanyId); cmd.Parameters.Add(parameter);
cmd.ExecuteNonQuery();
In der oben in der letzten Zeile gezeigt, das gleiche tun ich in Dutzenden von anderen Orten buchstäblich getan haben (Einsatzdaten, die ID-Spalte lesen und erfassen), erhalte ich folgendes:
Setup: System.InvalidOperationException: ExecuteNonQuery erfordert eine offene und verfügbare Verbindung. Der aktuelle Status der Verbindung ist geschlossen. bei System.Data.SqlClient.SqlConnection.GetOpenConnection (String-Methode)
ABER - ersetzen cmd mit neuen Variablen myCmd, und alles funktioniert swimmingly!
SqlCommand myCmd;
myCmd = new SqlCommand("INSERT INTO Subscription (User_ID, Name, Active) VALUES (@User_ID, @Name, @Active)", conn);
parameter = new SqlParameter("@User_ID", TestUserID); myCmd.Parameters.Add(parameter);
parameter = new SqlParameter("@Name", "TestSubscription"); myCmd.Parameters.Add(parameter);
parameter = new SqlParameter("@Active", true); myCmd.Parameters.Add(parameter);
myCmd.ExecuteNonQuery();
myCmd = new SqlCommand("SELECT Subscription_ID FROM [Subscription] WHERE Name = 'TestSubscription'", conn);
parameter = new SqlParameter("@User_ID", TestUserID);
myCmd.Parameters.Add(parameter);
using (dr = myCmd.ExecuteReader())
{
while (dr.Read())
{
TestSubscriptionID = dr.GetInt32(dr.GetOrdinal("Subscription_ID"));
}
}
myCmd = new SqlCommand("INSERT INTO SubscriptionCompany (Subscription_ID, Company_ID) VALUES (@Subscription_ID, @Company_ID)", conn);
parameter = new SqlParameter("@Subscription_ID", TestSubscriptionID); myCmd.Parameters.Add(parameter);
parameter = new SqlParameter("@Company_ID", KnownCompanyId); myCmd.Parameters.Add(parameter);
myCmd.ExecuteNonQuery();
Was zum Teufel geht hier vor? Wurde mein Befehl var einfach nur müde ???
Was mich an die "Lösung" erinnerte war, dass ich in meinem Tracing merkte, dass mein cmd.Parameters Block in meinem Block "lese die ID" nur EINEN Parameter enthielt, den zweiten, und als ich gezwungen wurde erste cmd.Parameters.Add Zeile erneut auszuführen, die Anzahl der Parameter in der Liste fiel auf 0. Das hat mich dazu veranlasst, eine Methode Ebene SqlCommand versuchen ... weil ich die verrückte Idee hatte, dass mein cmd müde war ... Stellen Sie sich vor mein Schock, als ich mich als richtig herausstellte!
Edit: Ich recycle keine Objekte hier - nur die Variable selbst (statische SqlCommand auf Klassenebene). Ich entschuldige mich für die frühere Verwirrung in meiner Formulierung der Frage.
Ja, das habe ich gerade selbst bemerkt. Festsetzung. –
@marc_s: Sie sind nur in der Größe reduziert. Machen Sie ein 'Bild anzeigen' rechtsklicken Sie auf sie und sie sind lesbar. –
Zu spät - bereits mit Codeschnipsel ersetzt –