执行非查询:连接属性尚未初始化
本文关键字:初始化 属性 连接 查询 执行 | 更新日期: 2023-09-27 18:31:49
下午, 所以我已经在这个问题上呆了几个小时,真的无法克服这最后一个驼峰。 下面是我正在编写的这个程序的代码:
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();我收到以下错误:
执行非查询:连接属性尚未初始化。
关于我错过了什么的任何想法?
需要将连接分配给SqlCommand
,可以使用构造函数或属性:
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 将创建,打开和关闭物理连接,而只是查看连接池中的可用连接。然而,这是一个不必要的开销。
您没有初始化连接。这就是为什么这种错误会来找你。
您的代码:
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);
这里有几件事是错误的。
-
是否确实要打开和关闭每个日志条目的连接?
-
你不应该使用
SqlCommand
而不是SqlDataAdapter
吗? -
数据适配器(或
SqlCommand
)需要的正是错误消息告诉您缺少的内容:活动连接。仅仅因为您创建了一个连接对象并不能神奇地告诉 C# 它是您要使用的对象(尤其是在尚未打开连接的情况下)。
我强烈推荐C#/SQL Server教程。
实际上,当服务器建立连接但由于无法识别连接函数标识符而无法构建时,会发生此错误。这个问题可以通过在代码中键入连接函数来解决。为此,我举一个简单的例子。在这种情况下,功能是con,您可能会有所不同。
SqlCommand cmd = new SqlCommand("insert into ptb(pword,rpword) values(@a,@b)",con);
打开和关闭连接需要花费大量时间。 并按照另一位成员的建议使用"使用"。我稍微更改了您的代码,但将 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
}
试试这个。
在执行ExecuteNonQuery()
之前,您需要在 SqlCommand.Connection
对象上使用 connection.open()
打开连接
双击表单以创建form_load事件。然后在该事件中写入命令.连接="您的连接名称";