大家好我有一个表单...如果用户点击提交按钮我会设置我的属性然后我将调用我的add_data函数,其中包含我的数据库查询......但问题是属性我'在我的表单中设置将在我的add_data函数中变空...为什么会发生这种情况?
实际上我已经尝试在设置我的属性值后在我的表单中添加一个包含我的属性中的数据的消息框并且它工作正常但是当我将它添加到我的databasecon类时,messagebox显示为null ...我也试着把我的属性和数据库查询函数在同一个类中,它正在工作,但我想要的是分离我的属性和我的数据库查询函数...
这是我的属性中的代码
class persons
{
//person attributes
private string fname;
private string lname;
private string age;
private string gnder;
private string address;
//initialize
public persons()
{
this.fname = "";
this.lname = "";
this.age = "";
this.gnder = "";
this.address = "";
}
//set and get properties
public string p_fname
{
get { return this.fname; }
set { this.fname = value; }
}
public string p_lname
{
get { return this.lname; }
set { this.lname = value; }
}
public string p_age
{
get { return this.age; }
set { this.age = value; }
}
public string p_gender
{
get { return this.gnder; }
set { this.gnder = value; }
}
public string p_address
{
get { return this.address; }
set { this.address = value; }
}
}
这是我表格中的代码
public partial class add : Form
{
persons p = new persons();
databasecon d = new databasecon();
private void addbtn_Click(object sender, EventArgs e)
{
p.p_fname = this.fname.Text;
p.p_lname = this.lname.Text;
p.p_age = this.age.Text;
p.p_gender = this.gender.Text;
p.p_address = this.address.Text;
d.add_data();
this.Close();
}
}
这是我的数据库连接和查询中的代码
class databasecon
{
OleDbConnection con = new OleDbConnection();
persons p = new persons();
public databasecon()
{
con.ConnectionString = "Provider=Microsoft.JET.OLEDB.4.0;Data Source=../dbsample.mdb";
}
public void add_data()
{
try
{
con.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO person(u_fname,u_lname,u_age,u_gender,u_address)VALUES('" + p.p_fname + "','" + p.p_lname + "','" + p.p_age + "','" + p.p_gender + "','" + p.p_address + "')";
cmd.Parameters.AddWithValue("u_fname", p.p_fname);
cmd.Parameters.AddWithValue("u_lname", p.p_lname);
cmd.Parameters.AddWithValue("u_age", p.p_age);
cmd.Parameters.AddWithValue("u_gender", p.p_gender);
cmd.Parameters.AddWithValue("u_address", p.p_address);
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
MessageBox.Show("Error : " + e);
}
finally
{
con.Close();
MessageBox.Show("New person has been successfully added.");
}
}
}
答案 0 :(得分:4)
您需要将p
作为参数传递给add_data
方法。
public void add_data(persons person)
然后用参数:
调用它d.add_data(p);
并在方法中使用person
的属性:
cmd.Parameters.AddWithValue("u_fname", person.p_fname);
cmd.Parameters.AddWithValue("u_lname", person.p_lname);
cmd.Parameters.AddWithValue("u_age", person.p_age);
cmd.Parameters.AddWithValue("u_gender", person.p_gender);
cmd.Parameters.AddWithValue("u_address", person.p_address);
答案 1 :(得分:1)
您在表单中创建databasecon(),然后调用add_data方法,并且您不传递'persons'实例。在databasecon中,你使用的是istnace,这是该类中的字段。你soudl添加参数do add_data方法并传递你要保存的实例或'人'并在命令中使用它
答案 2 :(得分:1)
p
和add
类中的databasecon
个字段是分开的。当您致电d.add_data()
时,d
对象只能看到persons p ...
的实例。
要解决此问题,请将persons
对象传递给add_data方法。
class databasecon{
// Remove this line, we pass it into the function below
/* persons p = new persons(); */
public void add_data(persons p){
try{
// same code as before
}catch(Exception e){
// same code
}
finally{
// same
}
}
}
答案 3 :(得分:1)
您有一个Person类的实例,您可以填充该类,然后使用databasecon的一个实例,该实例完全不符合您填写的人员类。 将add_data()更改为
public void add_data(person p) { ... }
这将使用p作为参数传递的属性。
你这样称呼它
d.add_data(p);
除此之外,请查看一些C#for begginers book。
答案 4 :(得分:1)
忽略你的代码编写得非常糟糕的事实。
您没有传入您创建的persons
课程。
像
这样的东西public void add_data(persons p) {//..blah}
然后
private void addbtn_Click(object sender, EventArgs e) {
p.p_fname = this.fname.Text;
p.p_lname = this.lname.Text;
p.p_age = this.age.Text;
p.p_gender = this.gender.Text;
p.p_address = this.address.Text;
d.add_data(p);
this.Close();
}
答案 5 :(得分:1)
从上面的代码中我可以看到,您从add_data
类调用databasecon
,该类具有Person的p
实例。由于您没有将Person对象传递给add_data
方法,因此空的未设置p
对象将保存到数据库中。
将一个Person参数添加到add_data,并在将数据保存到数据库时使用它。
答案 6 :(得分:1)
我的代码中有几件我不喜欢的东西。
让我们从你的具体问题开始:
您的代码还包含安全问题和恶意SQL代码注入的来源。
您总是保存一个空人,并且SQL连接字符串存在问题。
请尝试使用此代码。
private void addbtn_Click(object sender, EventArgs e)
{
try
{
persons p = new persons(); // we use a new instance of person class
p.p_fname = this.fname.Text;
p.p_lname = this.lname.Text;
p.p_age = this.age.Text;
p.p_gender = this.gender.Text;
p.p_address = this.address.Text;
d.add_data(p); // we save the instance of persons
this.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error : " + e);
}
}
...
class databasecon
{
public void add_data(person p) // we need a person as parameter
{
OleDbConnection con = new OleDbConnection();
con.ConnectionString = "Provider=Microsoft.JET.OLEDB.4.0;Data Source=../dbsample.mdb";
con.Open();
try
{
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
// this is the correct sql command string
cmd.CommandText = "INSERT INTO person(u_fname,u_lname,u_age,u_gender,u_address) " +
VALUES (@u_fname, @u_lname, @u_age, @u_gender, @u_address)";
cmd.Parameters.AddWithValue("u_fname", p.p_fname);
cmd.Parameters.AddWithValue("u_lname", p.p_lname);
cmd.Parameters.AddWithValue("u_age", p.p_age);
cmd.Parameters.AddWithValue("u_gender", p.p_gender);
cmd.Parameters.AddWithValue("u_address", p.p_address);
cmd.ExecuteNonQuery();
}
finally
{
con.Close();
}
}
...
}
现在让我们谈谈代码风格。
在代码中使用CamelCase样式是一件好事,在网上查看C#CamelCase: 类和属性都应以大写字母开头。
您的班级表达的是一个人而非人员名单,因此其名称应为public class Person
。
尽可能避免使用achronims或短名称... p_lname应该是LastName,如果你使代码更具可读性,人们会感谢你,C#不是C而C#不是PHP!
具有较长名称的字段或属性不会比具有短且不可读名称的属性消耗更多内存:)
始终使用强类型... age不是字符串,age是整数。
该属性应为public int Age
,而不是字符串!
永远不要在非可视类中使用MessageBox。 尝试捕获客户端代码中的异常,而不是库代码中的异常!
答案 7 :(得分:0)
我不知道我是否100%理解我的问题,因为你在数据库中插入了一个空的persons
类。
你的`add_data方法应该像这样一个人对象。
public void add_data(persons obj)
{
p = obj;
答案 8 :(得分:0)
您必须将person对象传递给add_data方法
public void add_data(persons p)
{
...
}
并称之为:
d.add_data(p);