我是C#的新手,并且在这里发表过第一篇文章。我正在写一个Windows窗体应用程序,用作数据库输入工具。为此,我要连接到访问数据库以读取列表并捕获新输入
我得到的错误是:
System.InvalidOperationException:'ExecuteReader:连接属性尚未初始化。'
在
OleDbDataReader reader = cmd.ExecuteReader();
导致错误的表格代码为:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.OleDb;
namespace Metrics_Data
{
public partial class Login : Form
{
Welcome conndata = new Welcome();
public Login()
{
InitializeComponent();
}
private void btn_exit_Click(object sender, EventArgs e)
{
this.Close();
}
private void Login_Load(object sender, EventArgs e)
{
}
private void btn_login_Click(object sender, EventArgs e)
{
//Verify Password and UserID
string Password = null;
OleDbCommand cmd = new OleDbCommand("SELECT * from [Users] WHERE UserID = @UserID",conndata.myconn);
cmd.Parameters.Add("@UserID", OleDbType.VarChar).Value = txt_userid;
OleDbDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Password = reader["User_Password"].ToString();
}
reader.Close();
cmd.Dispose();
//Load Next Form
UserHome userHomeform = new Metrics_Data.UserHome();
this.Hide();
userHomeform.ShowDialog();
}
}
}
从欢迎屏幕连接的代码为:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.OleDb;
using Microsoft.Win32;
namespace Metrics_Data
{
public partial class Welcome : Form
{
public OleDbConnection myconn = null;
public Welcome()
{
try
{
InitializeComponent();
OleDbConnection myconn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\148.96.211.237\GroupShares\Quality\Electronic Checksheets\MD.accdb;jet OLEDB:Database Password=""Warranty""");
myconn.Open();
lbl_Connstatus.Text = "Connected to DB";
p_dbconn.Visible = true;
}
catch(Exception)
{
MessageBox.Show("error connecting to DB");
btn_cfg.Visible = false;
btn_home.Visible = false;
btn_help.Visible = true;
}
}
class Variables
{
public static dynamic LoginType;
public static dynamic UserID;
public static dynamic Admin;
public static dynamic FirstUse;
public static dynamic Zone;
public static dynamic Shift;
public static dynamic Group;
public static dynamic CDate;
public static dynamic GateLevel;
public static dynamic CountermeasureID;
}
private void Welcome_Load(object sender, EventArgs e)
{
}
private void btn_help_Click(object sender, EventArgs e)
{
//If program is unable to connect with database, initiate sequence where computer's installed access database engine's are displayed in popups, then tell user that program cannot connect
//popups are displayed to help user. If no database engine popups are displayed, see the following URL for troubleshooting information:
//https://support.microsoft.com/en-us/help/2874601/can-t-use-the-access-odbc-driver-or-oledb-provider-outside-office-clic
//A possible fix to this problem is to install access runtime 2013. The URL below has the link to where it's stored locally:
//\\10.35.193.112\Open\AccessRuntime2013
//Update: This also resolves concerns for computers with MS Office 2016, in which the user will receive a popup indicating they have an OLEDB database engine, but the program still will
//not work. IT may be required to give users temporary administrative rights to install AccessRuntime2013.
string AccessDBAsValue = string.Empty;
RegistryKey rkACDBKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes");
if (rkACDBKey != null)
{
foreach (string subKeyName in rkACDBKey.GetSubKeyNames())
{
if (subKeyName.Contains("Microsoft.ACE.OLEDB"))
{
MessageBox.Show(Convert.ToString(subKeyName));
}
}
}
MessageBox.Show("The program was unable to connect to the database.");
}
private void btn_exit_Click(object sender, EventArgs e)
{
Environment.Exit(1);
}
private void btn_home_Click(object sender, EventArgs e)
{
Login loginform = new Metrics_Data.Login();
Variables.LoginType = "Data Entry";
loginform.ShowDialog();
}
关于我在这里做错什么的任何想法???我已经验证了数据库的路径,并且初始连接时的连接字符串没有给出任何错误,在Visual Studio的错误空间中也没有任何错误。
非常感谢!
答案 0 :(得分:0)
正如注释中指出的那样,您的构造函数是隐藏具有本地变量的表单属性myconn
,因此,当您引用form属性时,它将为null。
但是,如果我不建议您不要将连接存储在form属性中,那我将被撤职。 ADO.NET连接是池化的,通常创建起来很便宜,因此只需在需要时创建一个连接,并在处理完要为其创建的查询后就将其处置(使用using
)。
您可以将连接字符串存储在一个位置,但是共享连接对象通常不是一个好主意。
不使用共享连接也会使连接变得更简单,因为您不必担心检查连接是否打开,也不必担心打开两次,等等。