I'm trying to add some data from a SQLite database, inside a ListView.
I'm having some difficulties as I want to insert all the data of the column and not a single record.
TEST CODE:
Form1.cs {Load}
private void home_form_Load(object sender, EventArgs e)
{
listView1.Refresh();
listView1.View = View.Details;
listView1.Columns.Add("ID");
listView1.Columns.Add("Grado");
listView1.Columns.Add("Cognome");
listView1.Columns.Add("Nome");
listView1.Columns.Add("Status");
}
Form1.cs {menu_button_gestionepax}
private void menu_button_gestionepax_Click(object sender, EventArgs e)
{
menu_button_dashboard.BackColor = System.Drawing.Color.DeepSkyBlue;
panel_dashboard.Visible = false;
gestionepersonale_panel.Visible = true;
menu_button_gestionepax.BackColor = System.Drawing.Color.Blue;
listView1.Refresh();
ListViewItem lst = new ListViewItem();
lst.SubItems.Add(LoadUsers.ManagerFind());
lst.SubItems.Add(LoadUsers.ManagerFind());
lst.SubItems.Add(LoadUsers.ManagerFind());
lst.SubItems.Add(LoadUsers.ManagerFind());
lst.SubItems.Add(LoadUsers.ManagerFind());
listView1.Items.Add(lst);
/*
string[] row = { LoadUsers.ManagerFindid(), LoadUsers.ManagerFindid() };
var listViewItem = new ListViewItem(row);
infobox_listview.Items.Add(listViewItem);
*/
}
LoadUsers.cs
public dynamic string ManagerFind()
{
using (IDbConnection cnn = new SQLiteConnection(LoadConnectionString()))
{
var select = cnn.Query($"select id from utenti");
if (select.Any())
{ return select[0].ToString(); }
else return "wrong";
}
}
I have also done various other tests and one of the difficulties in some cases is to call string ManagerFind() from LoadUsers.cs
Try something like this to get your rows and columns from your sql i know this is how you do it in SQL im sure there is a similar way to do it with sqlLite
using (SqlConnection connection = new SqlConnection(_sqlConnectionStringFromUserImput))
{
connection.Open();
if (connection.State == ConnectionState.Open)
{
SqlCommand sqlCommand =
new SqlCommand(
"select id from utenti",
connection)
{
CommandType = CommandType.Text,
CommandTimeout = 20
};
SqlDataReader reader = sqlCommand.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
DateTime datetimefield = reader.GetFieldValue<DateTime>(0);
string stringField = reader.GetFieldValue<string>(1);
}
}
reader.Close();
}
connection.Close();
}
Related
I'm trying to insert data to a SQL Server with a dataGridView.
Here's what I have now in my buttonSave_Click :
string conString = "xxxxxxxx";
using (SqlConnection con = new SqlConnection(conString))
{
con.Open();
foreach (DataGridViewRow row in dataGridViewStock.Rows)
{
SqlCommand insert = new SqlCommand("INSERT INTO stock_test(size,quantity,codeArticleComponent) VALUES (#size,#quantity,#codeArticleComponent)", con);
if (row.Cells[0].Value != null && row.Cells[1].Value != null)
{
insert.Parameters.AddWithValue("#size", row.Cells[0].Value);
insert.Parameters.AddWithValue("#quantity", row.Cells[1].Value);
insert.Parameters.AddWithValue("#codeArticleComponent", labelComponentChosen.Text);
}
insert.ExecuteNonQuery();
insert.Parameters.Clear();
}
For now this piece of code has a weird behavior because it throws an exception System.Data.SqlClient.SqlException : Must declare the scalar variable "#size" but what I wrote in the cells is still added to the database.
very likely command cannot be executed on last DataGridView row, which is reserved for new item input. and all previous items are inserted properly.
it happens because (row.Cells[0].Value != null && row.Cells[1].Value != null) check for that row returns false and parameters are not added. the next statement insert.ExecuteNonQuery(); tries to run a command without required parameters and fails
create and execute insert command only for valid rows:
foreach (DataGridViewRow row in dataGridViewStock.Rows)
{
if (row.Cells[0].Value != null && row.Cells[1].Value != null)
{
SqlCommand insert = new SqlCommand("INSERT INTO stock_test(size,quantity,codeArticleComponent) VALUES (#size,#quantity,#codeArticleComponent)", con);
insert.Parameters.AddWithValue("#size", row.Cells[0].Value);
insert.Parameters.AddWithValue("#quantity", row.Cells[1].Value);
insert.Parameters.AddWithValue("#codeArticleComponent", labelComponentChosen.Text);
insert.ExecuteNonQuery();
}
}
string conString = "xxxxxxxx";
using (SqlConnection con = new SqlConnection(conString))
{
con.Open();
foreach (DataGridViewRow row in dataGridViewStock.Rows)
{
SqlCommand insert = new SqlCommand();
if (row.Cells[0].Value != null && row.Cells[1].Value != null)
{
insert.Parameters.AddWithValue("#size", row.Cells[0].Value);
insert.Parameters.AddWithValue("#quantity", row.Cells[1].Value);
insert.Parameters.AddWithValue("#codeArticleComponent", labelComponentChosen.Text);
}
insert = ("INSERT INTO stock_test(size,quantity,codeArticleComponent) VALUES (#size,#quantity,#codeArticleComponent)", con);
insert.ExecuteNonQuery();
insert.Parameters.Clear();
}
The Error is occur as you are using the variable before declaring them. Please Declare them prior with value before using into the Query.
This should do what you want.
using System;
using System.Data;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
SqlCommand sCommand;
SqlDataAdapter sAdapter;
SqlCommandBuilder sBuilder;
DataSet sDs;
DataTable sTable;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string connectionString = "Data Source=.;Initial Catalog=pubs;Integrated Security=True";
string sql = "SELECT * FROM Stores";
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
sCommand = new SqlCommand(sql, connection);
sAdapter = new SqlDataAdapter(sCommand);
sBuilder = new SqlCommandBuilder(sAdapter);
sDs = new DataSet();
sAdapter.Fill(sDs, "Stores");
sTable = sDs.Tables["Stores"];
connection.Close();
dataGridView1.DataSource = sDs.Tables["Stores"];
dataGridView1.ReadOnly = true;
save_btn.Enabled = false;
dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
}
private void new_btn_Click(object sender, EventArgs e)
{
dataGridView1.ReadOnly = false;
save_btn.Enabled = true;
new_btn.Enabled = false;
delete_btn.Enabled = false;
}
private void delete_btn_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Do you want to delete this row ?", "Delete", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
dataGridView1.Rows.RemoveAt(dataGridView1.SelectedRows[0].Index);
sAdapter.Update(sTable);
}
}
private void save_btn_Click(object sender, EventArgs e)
{
sAdapter.Update(sTable);
dataGridView1.ReadOnly = true;
save_btn.Enabled = false;
new_btn.Enabled = true;
delete_btn.Enabled = true;
}
}
}
You can find LOTS of great examples from the link below.
http://csharp.net-informations.com/datagridview/csharp-datagridview-database-operations.htm
I have a List (listOfQuestionIDs) stored in ViewState of 10 different numbers and an int counter (questionCounter) stored in ViewState which I intend to use to access the different numbers in the first list.
However, as I increment the value of ViewState["questionCounter"] by 1 the contents of listOfAnswerIDs and listOfAnswers remain exactly the same in the code below. Why is this?
protected void getAnswers()
{
string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
MySqlConnection conn = new MySqlConnection(connStr);
MySqlDataReader reader;
List<int> listOfQuestionIDs = (List<int>)(ViewState["listOfQuestionIDs"]);
int questionCounter = Convert.ToInt32(ViewState["questionCounter"]);
List<string> listOfAnswerIDs = new List<string>();
List<string> listOfAnswers = new List<string>();
List<string> listOfCorrectAnswerIDs = new List<string>();
try
{
conn.Open();
string cmdText = "SELECT * FROM answers WHERE question_id=#QuestionID";
MySqlCommand cmd = new MySqlCommand(cmdText, conn);
cmd.Parameters.Add("#QuestionID", MySqlDbType.Int32);
cmd.Parameters["#QuestionID"].Value = Convert.ToInt32(listOfQuestionIDs[questionCounter]);
reader = cmd.ExecuteReader();
while (reader.Read())
{
listOfAnswerIDs.Add(reader["answer_id"].ToString());
listOfAnswers.Add(reader["answer"].ToString());
if (reader["correct"].ToString().Equals("Y"))
{
listOfCorrectAnswerIDs.Add(reader["answer_id"].ToString());
}
}
for (int i = 0; i < listOfAnswerIDs.Count; i++)
{
lblTitle.Text += listOfAnswerIDs[i].ToString();
}
reader.Close();
populateAnswers(listOfAnswerIDs.Count, listOfAnswers, listOfAnswerIDs);
}
catch
{
lblError.Text = "Database connection error - failed to read records.";
}
finally
{
conn.Close();
}
ViewState["listOfQuestionIDs"] = listOfQuestionIDs;
ViewState["listOfCorrectAnswerIDs"] = listOfCorrectAnswerIDs;
}
Here's where I increment the questionCounter:
protected void btnNext_Click(object sender, EventArgs e)
{
.........
getNextQuestion();
}
protected void getNextQuestion()
{
int questionCounter = Convert.ToInt32(ViewState["QuestionCounter"]);
..........
getAnswers();
................
questionCounter += 1;
ViewState["QuestionCounter"] = questionCounter;
}
ViewState keys are case sensitive. In getAnswers() you use "questionCounter" and in getNextQuestion() you use "QuestionCounter". Pick one and keep it consistent.
I dynamically create a RadioButtonList or a CheckBoxList depending on a condition within a Button_Click event (which works).
protected void btnGetQuestion_Click(object sender, EventArgs e)
{
string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
MySqlConnection conn = new MySqlConnection(connStr);
MySqlDataReader reader;
List<string> listOfAnswerIDs = new List<string>();
List<string> listOfAnswers = new List<string>();
List<string> listOfCorrectAnswerIDs = new List<string>();
int questionCounter = 0;
//get questionIDs and store in ViewState["listOfQuestionIDs"]
getListOfQuestionIDs();
try
{
conn.Open();
string cmdText = "SELECT * FROM questions_m WHERE question_id=#QuestionID";
MySqlCommand cmd = new MySqlCommand(cmdText, conn);
cmd.Parameters.Add("#QuestionID", MySqlDbType.Int32);
cmd.Parameters["#QuestionID"].Value = listOfQuestionIDs[questionCounter];
reader = cmd.ExecuteReader();
if (reader.Read())
{
lblQuestion.Text = reader["question"].ToString();
if (reader["type"].ToString().Equals("C"))
{
CheckBoxList cblAnswers = new CheckBoxList();
cblAnswers.ID = "cblAnswers";
Page.Form.Controls.Add(cblAnswers);
}
else if (reader["type"].ToString().Equals("R"))
{
RadioButtonList rblAnswers = new RadioButtonList();
rblAnswers.ID = "rblAnswers";
Page.Form.Controls.Add(rblAnswers);
}
questionCounter += 1;
ViewState["questionCounter"] = questionCounter;
ViewState["QuestionID"] = Convert.ToInt32(reader["question_id"]);
reader.Close();
string cmdText2 = "SELECT * FROM answers WHERE question_id=#QuestionID";
MySqlCommand cmdAnswers = new MySqlCommand(cmdText2, conn);
cmdAnswers.Parameters.Add("#QuestionID", MySqlDbType.Int32);
cmdAnswers.Parameters["#QuestionID"].Value = ViewState["QuestionID"];
reader = cmdAnswers.ExecuteReader();
while (reader.Read())
{
listOfAnswerIDs.Add(reader["answer_id"].ToString());
listOfAnswers.Add(reader["answer"].ToString());
}
reader.Close();
populateAnswers(listOfAnswers, listOfAnswerIDs);
}
reader.Close();
}
catch
{
lblError.Text = "Database connection error - failed to read records.";
}
finally
{
conn.Close();
}
}
I want to create a method that I can run in another button click event (btnNext_Click) that will remove the RadioButtonList or CheckBoxList if one exists.
I've tried the following but it doesn't seem to work:
protected void clearAnswers()
{
if (((CheckBoxList)this.FindControl("cblAnswers")) != null)
{
Page.Form.Controls.Remove(this.FindControl("cblAnswers"));
}
if (((RadioButtonList)this.FindControl("rblAnswers")) != null)
{
Page.Form.Controls.Remove(this.FindControl("rblAnswers"));
}
}
UPDATE:
I think the issue I had occured with the repopulation of the RadioButtonList/CheckBoxList. If I cleared each item before repopulating them, that resolved my problem.
if (((CheckBoxList)this.FindControl("cblAnswers")) != null)
{
((CheckBoxList)this.FindControl("cblAnswers")).Items.Clear();
foreach (int num in numbers)
{
((CheckBoxList)this.FindControl("cblAnswers")).Items.Add(ans[num - 1]);
}
}
if (((RadioButtonList)this.FindControl("rblAnswers")) != null)
{
((RadioButtonList)this.FindControl("rblAnswers")).Items.Clear();
foreach (int num in numbers)
{
((RadioButtonList)this.FindControl("rblAnswers")).Items.Add(ans[num - 1]);
}
}
Try this:
protected void clearAnswers()
{
CheckBoxList cblAnswers = (CheckBoxList)this.FindControl("cblAnswers");
RadioButtonList rblAnswers = (RadioButtonList)this.FindControl("rblAnswers");
if (cblAnswers != null)
{
Page.Form.Controls.Remove(cblAnswers);
}
if (rblAnswers != null)
{
Page.Form.Controls.Remove(rblAnswers);
}
}
Hi im new to programming and currently working on a project that lets a user enter its
registration data into a local database using textBoxes. The code works that its adding the items into the database
and after i press a "Show_users" button it displays them in the listBox_users listbox.
My problem is that when i choose a name from the listBox_users it should dislay the data about the selected user in the upper textBox'es i used to enter
the data in the first place using the event i created for the listBox_users,
but im getting an error that "can't read data from database that is already closed".
namespace Userform
{
public partial class Form1: Form
{
SqlCeDataReader rdr;
public Form1()
{
InitializeComponent();
}
// Some code between...
private void button_ShowUsers_Click(object sender, EventArgs e) //code that shows users in listBox
{
var dt = new DataTable();
string connectionString2 = #"Data Source=MyDatabase;Password=xxxxxx;";
using (var cn = new SqlCeConnection(connectionString2))
using (var cmd = new SqlCeCommand("Select * From Users", cn))
{
cn.Open();
using (var reader = cmd.ExecuteReader())
{
dt.Load(reader);
var results = (from row in dt.AsEnumerable()
select new
{
//UserID = row.Field<int>("ID"),
FirstName = row.Field<string>("Firsname"),
LastName = row.Field<string>("Lastname"),
FullName = row.Field<string>("Firstname") + " " + row.Field<string>("Lastname")
}).ToList();
listBox_users.DataSource = results;
listBox_users.DisplayMember = "FullName";
rdr = cmd.ExecuteReader();
}
}
}
//I made an event for the listBox_users:
private void listBox_users_SelectedIndexChanged(object sender, EventArgs e)
//event code that should show listbox selected data in the textBoxes
{
if (listBox_inimesed.SelectedItem != null && rdr != null)
{
try
{
if (rdr.Read())
{
textBox1_firstname.Text = rdr.GetString(1);
textBox2_lastname.Text = rdr.GetString(2);
textBox3_email.Text = rdr.GetString(3);
textBox4_address.Text = rdr.GetString(4);
dateTimePicker1.Value = rdr.GetDateTime(5);
richTextBox_info.Text = rdr.GetString(6);
}
else MessageBox.Show("Object not found");
}
finally
{
rdr.Close();
}
}
}
}
The connection that the reader you are using is dependent on has been closed in the button_ShowUsers_Click event.
It is not a good practice to try to share connections and DataReaders across events. That will result in open connections that are not disposed of correctly. A better practice would be to have the creation of the Connection, Command, and DataReader take place in each event method. By using the "using" statement they will be closed and disposed of correctly in each method. You can also remove the class level variable "rdr".
namespace Userform
{
public partial class Form1 : Form
{
const string connectionString2 = #"Data Source=MyDatabase;Password=xxxxxx;";
public Form1()
{
InitializeComponent();
}
// Some code between...
private void button_ShowUsers_Click(object sender, EventArgs e) //code that shows users in listBox
{
var dt = new DataTable();
using (var cn = new SqlCeConnection(connectionString2))
using (var cmd = new SqlCeCommand("Select * From Users", cn))
{
cn.Open();
using (var reader = cmd.ExecuteReader())
{
dt.Load(reader);
var results = (from row in dt.AsEnumerable()
select new
{
//UserID = row.Field<int>("ID"),
FirstName = row.Field<string>("Firsname"),
LastName = row.Field<string>("Lastname"),
FullName = row.Field<string>("Firstname") + " " + row.Field<string>("Lastname")
}).ToList();
listBox_users.DataSource = results;
listBox_users.DisplayMember = "FullName";
}
}
}
//I made an event for the listBox_users:
private void listBox_users_SelectedIndexChanged(object sender, EventArgs e)
//event code that should show listbox selected data in the textBoxes
{
if (listBox_inimesed.SelectedItem != null)
{
using (var cn = new SqlCeConnection(connectionString2))
using (var cmd = new SqlCeCommand("Select * From Users", cn))
{
cn.Open();
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
textBox1_firstname.Text = reader.GetString(1);
textBox2_lastname.Text = reader.GetString(2);
textBox3_email.Text = reader.GetString(3);
textBox4_address.Text = reader.GetString(4);
dateTimePicker1.Value = reader.GetDateTime(5);
richTextBox_info.Text = reader.GetString(6);
}
else MessageBox.Show("Object not found");
}
}
}
}
}
}
I wanted to read all data from a table(containg 3 rows) and to add all the data into generic collection.From collection i wana bind to gridview.
The code displayed below works but only last row is displayed 3 times in gridview.Can You help me.Am a beginer
protected void Page_Load(object sender, EventArgs e)
{
List<Student> listid = new List<Student>();
Student stud = new Student();
SqlConnection con = new SqlConnection("........");
string sql = "select * from StudentInfo";
con.Open();
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
stud.Studid = Convert.ToInt32(dr["StudId"]);
stud.StudName = dr["StudName"].ToString();
stud.StudentDept = dr["StudentDept"].ToString();
listid.Add(stud);
}
GridView1.DataSource = listid;
GridView1.DataBind();
}
public class Student
{
private int studid;
public int Studid
{
get { return studid; }
set { studid = value; }
}
private string studName;
public string StudName
{
get { return studName; }
set { studName = value; }
}
private string studentDept;
public string StudentDept
{
get { return studentDept; }
set { studentDept = value; }
}
The output is like this:
You need to instantiate your object inside while loop
Otherwise you will have same data in the collection
So the code should be
protected void Page_Load(object sender, EventArgs e)
{
List<Student> listid = new List<Student>();
SqlConnection con = new SqlConnection("........");
string sql = "select * from StudentInfo";
con.Open();
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Student stud = new Student();
stud.Studid = Convert.ToInt32(dr["StudId"]);
stud.StudName = dr["StudName"].ToString();
stud.StudentDept = dr["StudentDept"].ToString();
listid.Add(stud);
}
GridView1.DataSource = listid;
GridView1.DataBind();
}
Also it is not a good practice to use while to data reader or directly open connection
You should use using statement.
using(SqlConnection con = new SqlConnection("connection string"))
{
con.Open();
using(SqlCommand cmd = new SqlCommand("SELECT * FROM SomeTable", connection))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader != null)
{
while (reader.Read())
{
//do something
}
}
} // reader closed and disposed up here
} // command disposed here
} //connection closed and disposed here
In the DataReader while loop instantiate a new Student for each row in the database table:
while (dr.Read())
{
var stud = new Student();
stud.Studid = Convert.ToInt32(dr["StudId"]);
stud.StudName = dr["StudName"].ToString();
stud.StudentDept = dr["StudentDept"].ToString();
listid.Add(stud);
}