ExecuteNonQuery:连接属性尚未初始化。

Posted

技术标签:

【中文标题】ExecuteNonQuery:连接属性尚未初始化。【英文标题】:ExecuteNonQuery: Connection property has not been initialized. 【发布时间】:2012-05-03 00:49:47 【问题描述】:

下午, 所以我已经在这个问题上讨论了几个小时,并且无法真正克服这最后一个问题。下面是我正在编写的这个程序的代码:

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

代码编译良好,没有错误或警告,但是当我运行它时,只要它到达 cmd.InsertCommand.ExecuteNonQuery();我收到以下错误:

关于我错过了什么的任何想法?

【问题讨论】:

cmd.InsertCommand.Connection = connection1; (顺便说一句,为每个日志条目打开一个新连接是不行的。) @Alan No it isn't,它们由 .NET 自动汇集。这里的禁忌是IDisposable 对象不在using 语句中,因此如果发生异常,连接将不会返回到池中。 【参考方案1】:

您需要将连接分配给SqlCommand,可以使用constructor 或property:

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

我强烈建议将using-statement 用于实现IDisposable 的任何类型,例如SqlConnection,它也会关闭连接:

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

除此之外,您不需要为foreach 中的每个条目创建新连接和DataAdapter,即使创建、打开和关闭连接确实意味着 ADO .NET 将创建、打开和关闭 物理 连接,但只是查看connection-pool 以获取可用连接。然而,这是不必要的开销。

【讨论】:

【参考方案2】:

您没有初始化连接。这就是为什么会出现这种错误。

您的代码:

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

更正的代码:

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

【讨论】:

【参考方案3】:

这里有一些问题。

    您真的要为每个日志条目打开和关闭连接吗?

    您不应该使用SqlCommand 而不是SqlDataAdapter吗?

    数据适配器(或SqlCommand)需要的正是错误消息告诉您它丢失的内容:活动连接。仅仅因为您创建了一个连接对象并不能神奇地告诉 C# 它是您要使用的对象(尤其是在您尚未打开连接的情况下)。

我强烈推荐 C#/SQL Server 教程。

【讨论】:

【参考方案4】:

其实这个错误是在服务器建立连接但由于无法识别连接函数标识符而无法构建时发生的。这个问题可以通过在代码中输入连接函数来解决。为此,我举一个简单的例子。在这种情况下,功能可能会有所不同。

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

【讨论】:

【参考方案5】:

打开和关闭连接需要很长时间。并按照另一位成员的建议使用“使用”。 我稍微更改了您的代码,但将 SQL 创建和打开和关闭放在您的循环之外。这应该会加快执行速度。

  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
        

【讨论】:

【参考方案6】:

试试这个..

在执行ExecuteNonQuery()之前,您需要在SqlCommand.Connection对象上使用connection.open()打开连接

【讨论】:

【参考方案7】:

双击您的表单以创建 form_load 事件。然后在该事件中写入 command.connection = "your connection name";

【讨论】:

以上是关于ExecuteNonQuery:连接属性尚未初始化。的主要内容,如果未能解决你的问题,请参考以下文章

错误 ExecuteNonQuery:连接属性尚未初始化 C# (Access)

VB.NET SQL Server 插入 - ExecuteNonQuery:连接属性尚未初始化

ExecuteNonQuery:尚未初始化Connection属性。

C# 中的事务和 ExecuteNonQuery 错误

Dapper事务操作

发送数据访问数据库