web-dev-qa-db-fra.com

ExecuteNonQuery: la propriété de connexion n'a pas été initialisée. 

Après midi, Donc, je suis à ce problème depuis des heures et je ne peux pas vraiment aller au-delà de cette dernière bosse. Ci-dessous le code de ce programme que j'écris: 

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

Le code se compile bien sans erreur ni avertissement, mais quand je vais l'exécuter, dès qu'il arrive à cmd.InsertCommand.ExecuteNonQuery (); Je reçois l'erreur suivante: 

ExecuteNonQuery: la propriété de connexion n'a pas été initialisée. 

Des idées sur ce que j'ai manqué?

12
jladd

Vous devez affecter la connexion à la SqlCommand. Vous pouvez utiliser le constructeur ou la propriété :

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

Je recommande fortement d'utiliser le using-statement pour tout type implémentant IDisposable comme SqlConnection, cela fermera également la connexion:

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
}

En dehors de cela, vous n'avez pas besoin de créer une nouvelle connexion et DataAdapter pour chaque entrée de la foreach, même si créer, ouvrir et fermer une connexion ne signifie pas que ADO.NET va créer, ouvrir et fermer un physical connexion mais cherche juste dans le connection-pool _ pour une connexion disponible. Néanmoins, c'est une surcharge inutile.

32
Rango

Vous n’initialisez pas la connexion. C’est pourquoi ce type d’erreur vous arrive. 

Votre code:

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

Code corrigé:

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

Un couple de choses ne va pas ici. 

  1. Voulez-vous vraiment ouvrir et fermer la connexion pour chaque entrée de journal?

  2. Ne devriez-vous pas utiliser SqlCommand au lieu de SqlDataAdapter?

  3. L'adaptateur de données (ou SqlCommand) a besoin exactement de ce que le message d'erreur vous dit qu'il manque: une connexion active. Le fait que vous ayez créé un objet de connexion ne dit pas comme par magie à C # que c'est celui que vous voulez utiliser (surtout si vous n'avez pas ouvert la connexion).

Je recommande fortement un tutoriel C #/SQL Server.

1
Aaron Bertrand

En réalité, cette erreur se produit lorsque le serveur établit la connexion mais ne peut pas se créer en raison d'un problème d'identification de la fonction de connexion. Ce problème peut être résolu en tapant la fonction de connexion dans le code. Pour cela, je prends un exemple simple. Dans ce cas, la fonction est con peut être différente.

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

Ouvrir et fermer la connexion prend beaucoup de temps. Et utilisez le mot "using" comme un autre membre l’a suggéré… .. J'ai légèrement modifié votre code, mais j'ai mis la création SQL ainsi que l'ouverture et la fermeture de votre boucle OUTSIDE. Ce qui devrait accélérer l'exécution un peu.

  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