web-dev-qa-db-de.com

ExecuteNonQuery: Die Verbindungseigenschaft wurde nicht initialisiert. 

Nachmittag, Ich war also stundenlang in dieser einen Ausgabe und kann diesen letzten Buckel nicht wirklich überwinden. Unten ist der Code für dieses Programm, das ich schreibe: 

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Diagnostics;  
using System.Data;  
using System.Data.SqlClient;  
using System.Configuration;  

namespace Test  
{  
  class Program  
  {  
    static void Main()  
    {  
      EventLog alog = new EventLog();  
      alog.Log = "Application";  
      alog.MachineName = ".";  
      foreach (EventLogEntry entry in alog.Entries)  
      {  
       SqlConnection connection1 = new SqlConnection(@"Data Source=.\sqlexpress;Initial Catalog=syslog2;Integrated Security=True");  
       SqlDataAdapter cmd = new SqlDataAdapter();  
       cmd.InsertCommand = new SqlCommand("INSERT INTO Application VALUES (@EventLog, @TimeGenerated, @EventType, @SourceName, @ComputerName, @InstanceId, @Message) ");  
       cmd.InsertCommand.Parameters.Add("@EventLog",SqlDbType.VarChar).Value = alog.Log;  
       cmd.InsertCommand.Parameters.Add("@TimeGenerated", SqlDbType.DateTime).Value = entry.TimeGenerated;  
       cmd.InsertCommand.Parameters.Add("@EventType", SqlDbType.VarChar).Value = entry.EntryType;  
       cmd.InsertCommand.Parameters.Add("@SourceName", SqlDbType.VarChar).Value = entry.Source;  
       cmd.InsertCommand.Parameters.Add("@ComputerName", SqlDbType.VarChar).Value = entry.MachineName;  
       cmd.InsertCommand.Parameters.Add("@InstanceId", SqlDbType.VarChar).Value = entry.InstanceId;  
       cmd.InsertCommand.Parameters.Add("@Message", SqlDbType.VarChar).Value = entry.Message;  
       connection1.Open();  
       cmd.InsertCommand.ExecuteNonQuery();  
       connection1.Close();  
      }   
    }  
  }  
} 

Der Code kann ohne Fehler oder Warnung kompiliert werden, aber wenn ich ihn ausführen werde, sobald er zu cmd.InsertCommand.ExecuteNonQuery () gelangt; Ich erhalte folgende Fehlermeldung: 

ExecuteNonQuery: Die Verbindungseigenschaft wurde nicht initialisiert. 

Irgendwelche Ideen, was ich vermisst habe?

12
jladd

Sie müssen die Verbindung der SqlCommand zuweisen. Sie können den Konstruktor oder die Eigenschaft verwenden:

cmd.InsertCommand = new SqlCommand("INSERT INTO Application VALUES (@EventLog, @TimeGenerated, @EventType, @SourceName, @ComputerName, @InstanceId, @Message) ");
cmd.InsertCommand.Connection = connection1;

Ich empfehle nachdrücklich die Verwendung des using-statement für jeden Typ, der IDisposable wie SqlConnection implementiert, es wird auch die Verbindung geschlossen:

using(var connection1 = new SqlConnection(@"Data Source=.\sqlexpress;Initial Catalog=syslog2;Integrated Security=True"))
using(var cmd = new SqlDataAdapter())
using(var insertCommand = new SqlCommand("INSERT INTO Application VALUES (@EventLog, @TimeGenerated, @EventType, @SourceName, @ComputerName, @InstanceId, @Message) "))
{
    insertCommand.Connection = connection1;
    cmd.InsertCommand = insertCommand;
    //.....
    connection1.Open();
    // .... you don't need to close the connection explicitely
}

Abgesehen davon müssen Sie keine neue Verbindung und DataAdapter für jeden Eintrag in der foreach erstellen, auch wenn beim Erstellen, Öffnen und Schließen einer Verbindung nicht bedeutet, dass ADO.NET ein physische Verbindung schaut aber nur in den connection-pool nach einer verfügbaren Verbindung. Trotzdem ist dies ein unnötiger Aufwand.

32
Rango

Sie initialisieren keine Verbindung. Deshalb kommt diese Art von Fehler zu Ihnen. 

Dein Code:

cmd.InsertCommand = new SqlCommand("INSERT INTO Application VALUES (@EventLog, @TimeGenerated, @EventType, @SourceName, @ComputerName, @InstanceId, @Message) ");

Korrigierter Code:

cmd.InsertCommand = new SqlCommand("INSERT INTO Application VALUES (@EventLog, @TimeGenerated, @EventType, @SourceName, @ComputerName, @InstanceId, @Message) ",connection1);
10
Prasad Bhosale

Ein paar Dinge sind hier falsch. 

  1. Möchten Sie die Verbindung wirklich für jeden Protokolleintrag öffnen und schließen?

  2. Sollten Sie nicht SqlCommand anstelle von SqlDataAdapter verwenden?

  3. Der Datenadapter (oder SqlCommand) benötigt genau das, was in der Fehlermeldung angezeigt wird, dass er fehlt: eine aktive Verbindung. Nur weil Sie ein Verbindungsobjekt erstellt haben, sagt C # nicht magisch, dass es das ist, das Sie verwenden möchten (insbesondere, wenn Sie die Verbindung nicht geöffnet haben).

Ich empfehle dringend ein C #/SQL Server-Tutorial.

1
Aaron Bertrand

Tatsächlich tritt dieser Fehler auf, wenn der Server eine Verbindung herstellt, aber aufgrund eines Fehlers beim Identifizieren der Verbindungsfunktions-ID nicht aufgebaut werden kann. Dieses Problem kann durch Eingabe der Verbindungsfunktion in den Code gelöst werden. Dafür nehme ich ein einfaches Beispiel. In diesem Fall kann die Funktion jedoch anders sein.

SqlCommand cmd = new SqlCommand("insert into ptb(pword,rpword) values(@a,@b)",con);
1
waseem

Das Öffnen und Schließen der Verbindung erfordert viel Zeit. Und verwenden Sie das "using" als ein anderes Mitglied, das vorgeschlagen wird . Ich habe Ihren Code leicht geändert, aber die SQL-Erstellung und das Öffnen und Schließen von OUTSIDE in Ihre Schleife eingefügt. Was die Ausführung etwas beschleunigen sollte.

  static void Main()
        {
            EventLog alog = new EventLog();
            alog.Log = "Application";
            alog.MachineName = ".";
            /*  ALSO: USE the USING Statement as another member suggested
            using (SqlConnection connection1 = new SqlConnection(@"Data Source=.\sqlexpress;Initial Catalog=syslog2;Integrated Security=True")
            {

                using (SqlCommand comm = new SqlCommand("INSERT INTO Application VALUES (@EventLog, @TimeGenerated, @EventType, @SourceName, @ComputerName, @InstanceId, @Message) ", connection1))
                {
                    // add the code in here
                    // AND REMEMBER: connection1.Open();

                }
            }*/
            SqlConnection connection1 = new SqlConnection(@"Data Source=.\sqlexpress;Initial Catalog=syslog2;Integrated Security=True");
            SqlDataAdapter cmd = new SqlDataAdapter();
            // Do it one line
            cmd.InsertCommand = new SqlCommand("INSERT INTO Application VALUES (@EventLog, @TimeGenerated, @EventType, @SourceName, @ComputerName, @InstanceId, @Message) ", connection1);
            // OR YOU CAN DO IN SEPARATE LINE :
            // cmd.InsertCommand.Connection = connection1;
            connection1.Open();

            // CREATE YOUR SQLCONNECTION ETC OUTSIDE YOUR FOREACH LOOP
            foreach (EventLogEntry entry in alog.Entries)
            {
                cmd.InsertCommand.Parameters.Add("@EventLog", SqlDbType.VarChar).Value = alog.Log;
                cmd.InsertCommand.Parameters.Add("@TimeGenerated", SqlDbType.DateTime).Value = entry.TimeGenerated;
                cmd.InsertCommand.Parameters.Add("@EventType", SqlDbType.VarChar).Value = entry.EntryType;
                cmd.InsertCommand.Parameters.Add("@SourceName", SqlDbType.VarChar).Value = entry.Source;
                cmd.InsertCommand.Parameters.Add("@ComputerName", SqlDbType.VarChar).Value = entry.MachineName;
                cmd.InsertCommand.Parameters.Add("@InstanceId", SqlDbType.VarChar).Value = entry.InstanceId;
                cmd.InsertCommand.Parameters.Add("@Message", SqlDbType.VarChar).Value = entry.Message;
                int rowsAffected = cmd.InsertCommand.ExecuteNonQuery();
            }
            connection1.Close(); // AND CLOSE IT ONCE, AFTER THE LOOP
        }
0
Ryno Potgieter