dataadapter.update() does not save to database - c#

The following code is not saving the changes from the dataset to the database via the dataadapter.update(). I display the data on a winform to text boxes.
I have a save button that should save the changes made to the database. the changes are only saved to the in memory copy of the dataset. what am i missing to get this to save the changes to the database?
public partial class Frm_Main : Form
{
DataSet ds = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter();
BindingSource binding_Login = new BindingSource();
SqlCommandBuilder builder = new SqlCommandBuilder();
SqlConnection connection = new SqlConnection();
SqlCommand sqlcommand = new SqlCommand();
public Frm_Main()
{
InitializeComponent();
}
private void FrmMain_Load(object sender, EventArgs e)
{
this.Text = "Main (" + GlobalVars.username.ToString() + ")";
this.AcceptButton = btnSearch;
connection.ConnectionString = GlobalVars.sqlConnString;
}
private void FrmMain_Close(object sender, EventArgs e)
{
Close();
}
private void btnSearch_Click(object sender, EventArgs e)
{
if(!string.IsNullOrEmpty(txtSearch.Text))
{
Search();
}
}
public void Search()
{
string sqlcommandstring = "select * from login where loginname like #search;";
connection.Open();
sqlcommand.CommandText = sqlcommandstring;
sqlcommand.Connection = connection;
sqlcommand.Parameters.AddWithValue("#search", "%" + txtSearch.Text + "%");
adapter.SelectCommand = sqlcommand ;
builder.DataAdapter = adapter;
adapter.Fill(ds,"Login") ;
BindControls();
txtLoginName.DataBindings.Add(new Binding("Text", binding_Login, "LoginName"));
txtPassword.DataBindings.Add(new Binding("Text", binding_Login, "Password"));
adapter.UpdateCommand = builder.GetUpdateCommand();
adapter.DeleteCommand = builder.GetDeleteCommand();
adapter.InsertCommand = builder.GetInsertCommand();
}
private void btnNext_Click(object sender, EventArgs e)
{
binding_Login.MoveNext();
}
protected void BindControls()
{
binding_Login.DataSource = ds.Tables[0];
}
private void btnPrevious_Click(object sender, EventArgs e)
{
binding_Login.MovePrevious();
}
private void btnSave_Click(object sender, EventArgs e)
{
ds.AcceptChanges();
adapter.Update(ds.Tables[0]);
}
}

I was able to resolve the issue by changing the save buttons click event to the following:
private void btnSave_Click(object sender, EventArgs e)
{
this.binding_Login.EndEdit();
adapter.Update(this.ds.Tables[0]);
}

The problem was in this line:
private void btnSave_Click(object sender, EventArgs e)
{
ds.AcceptChanges();//EDIT This is the problem!
adapter.Update(ds.Tables[0]);
}
I had a similar problem and during debbuging I realized that if you call .AcceptChanges() before DataAdapter.Update(), all your modified rows will change their status to Unchanged. This means that DataAdapter.Update() will lose all the flags it needs to pick the right INSERT, UPDATE, DELETE command.
I also had problems using editing batches like:
row.BeginEdit();
// Modify several rows
row.EndEdit();
As I understand, the problem here happens because all changes are reserved until you call the AcceptChanges() method, thus causing all the row state flags to be set as Unchanged, making DataAdapter.Update() essentially blind.
In short:
Create a DataAdapter.
Set the InsertCommand, UpdateCommand, DeleteCommand, SelectCommand.
Fill a DataSet, DataTable, DataRow[], with the adapter.
Make changes to your DataSet, DataTable, DataRow[].
Make sure these changes are flagged in the RowState property of the modified row(s).
To ensure this, don't use batch editing, and don't call AcceptChanges(), before the DataAdapter.Update() method.
Using the same adapter, call adapter.Update(DataSet|DataTable|DataRow[]).

Related

Load first columns from datagrid to textbox in c#

Im begginer in c # and I try to do a spin code that I found on the net.
My worry is that I would like the value of the first line of the datagrid, automatically loads itself when launching the form in a textbox.
I have this code that works fine, but it does not display any value in the textbox if I do not click on a datagrid line.
The code :
namespace SQLiteTEST
{
public partial class Form1 : Form
{
private SQLiteConnection connection;
private String SQLSelect = "SELECT * FROM User";
public Form1()
{
InitializeComponent();
connection = new SQLiteConnection("Data Source=BddTest.s3db;Version=3;");
}
private void search()
{
dataGrid1.RowEnter -= dataGrid_RowEnter;
if (connection.State != ConnectionState.Open)
connection.Open();
SQLiteCommand command = connection.CreateCommand();
command.CommandText = SQLSelect;
DataTable dt = new DataTable();
SQLiteDataAdapter da = new SQLiteDataAdapter(command);
da.Fill(dt);
dataGrid1.DataSource = dt;
connection.Close();
dataGrid1.RowEnter += dataGrid_RowEnter;
}
private void dataGrid_RowEnter(object sender, DataGridViewCellEventArgs e)
{
int ID = int.Parse(dataGrid1.Rows[e.RowIndex].Cells[0].Value.ToString());
String Data1 = (String)dataGrid1.Rows[e.RowIndex].Cells[1].Value;
txtId.Text = ID.ToString();
txtName.Text = Data1;
}
private void Form1_Load(object sender, EventArgs e)
{
search();
}
private void dataGrid_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
MessageBox.Show("erreur");
}
private void button1_Click(object sender, EventArgs e)
{
var form_programme = new Form2();
form_programme.Show();
this.Hide();
}
private void dataGrid1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
private void txtName_TextChanged(object sender, EventArgs e)
{
}
private void txtId_TextChanged(object sender, EventArgs e)
{
}
private void dataGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
}
}
How could I make the first line appear in the textbox as if I was clicking on it?
Thank you in advance for your advice or sample code.
Regard.
Create a method like this:
private object GetValue(int rowIndex, int columnIndex)
{
return dataGrid1.Rows[rowIndex].Cells[columnIndex].Value;
}
I would like the value of the first line of the datagrid, automatically loads itself when launching the form in a textbox.
Use that to get any value you need. In your search method, at the end, after the data is loaded into the grid, you just need to get the values from the first row:
// first row first column.
// Use TryParse if the value is not always a number. If always a number
// then Parse is good enough
int id = int.Parse(GetValue(0, 0).ToString());
string data1 = (String) GetValue(0, 1);
txtId.Text = id.ToString();
txtName.Text = data1;
Also use .NET naming conventions so your local variables should be camel case and your method names should be Pascal notation. search should be Search.
Finaly i find how to resolve my problem !
Ill do this :
public Form1()
{
InitializeComponent();
connection = new SQLiteConnection("Data Source=BddTest.s3db;Version=3;");
search();}
Regard.

i tried several techniques but failed to handle this error System.Data.SqlClient.SqlException' occurred in System.Data.dll

I have the following error occured when try to execute my program, do not know how to handle, following is the code , and i also attached the screenshots.
i am new to .net and sql. Thanks
public partial class adminInfo : Form
{
SqlCommandBuilder scb;
public adminInfo()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
PMS obj = new PMS();
obj.Show();
this.Hide();
}
private void button3_Click(object sender, EventArgs e)
{
adminAdd_delete obj = new adminAdd_delete();
obj.Show();
this.Hide();
}
private void button2_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\ddd\Desktop\Pharmacy managment system\Pharmacy managment system\adminInfo.mdf;Integrated Security=True;Connect Timeout=30");
SqlDataAdapter sda = new SqlDataAdapter(#"SELECT CNIC, [JOB TITLE], SALARY, NAME
FROM admininfo", con);
DataTable dt = new DataTable();
sda.Fill(dt);
dataGridView1.DataSource = dt;
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
}
}
Seems you're new comer to stackoverflow, I simply suggest to define the DataTable how it looks like,
DataTable dt= new DataTable("admininfo");
Now, the structure of DataTable is same as admininfo table in SQL database.
You just made a instance of DataTable but you need to set columns manually which belong to the DataTable or automatic way like above.
Hope this helps..

Update Table only works once in datagridview (c#)

I have a datagridview in which I have made cells editable. Once the user has entered any text, they hit the "UPDATE" button, it updates the database.
The problem is whenever I open the application, it does update only for the first time. When I try to make more modification and click "UPDATE" button, it fails to update database. Here is my code. Please suggest any solution
private void Form1_Load_1(object sender, EventArgs e)
{
con.Open();
sda = new SqlDataAdapter("Select * from Name", con);
ds = new System.Data.DataSet();
sda.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
}
private void button1_Click(object sender, EventArgs e)
{
scb = new SqlCommandBuilder(sda);
sda.Update(ds);
}
Actually, there is nothing wrong with the code I mentioned. Instead there was some another section which was causing db not to be updated.
I also kept a Refresh button with this code -
private void button2_Click(object sender, EventArgs e)
{
sda = new SqlDataAdapter("Select * from Name", con);
DataTable dt = new DataTable();
sda.Fill(dt);
dataGridView1.DataSource = dt;
}
Seems that it reverted back Update to original db content. Removing it worked successfully.

Data table in C#.net

I have a problem related to DataTable in .net.
i am trying to fill datatable on page_load .that part is ok no issue datatable correctly filled up with data. but I noticed that when I clicked button on page... it again try to fill datatable which just a time-consuming task... I want datatable should fill once only ,when , when site open in browser .. not at every click ... because I have a large amount of data in table so it takes time to load in datatable..
plz help me out ...
here is my code:
protectd void Page_Load(object sender, EventArgs e)
{
cnn.ConnectionString= ConfigurationManager.ConnectionStrings["con"].ConnectionString;
// if (this.IsPostBack == true)
{
dr1 = TableUtoP();
dtWordsList.Load(dr1);
}
}
OleDbDataReader TableUtoPunj(String ArrWord)
{
if (cnn.State == ConnectionState.Open)
{
cnn.Close();
}
cnn.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = "SELECT U, P from UtoP";
cmd.Connection = cnn;
OleDbDataReader dr = cmd.ExecuteReader();
return dr;
}
You need to check if the page is posting back or not, like this:
protected void Page_Load(object sender, EventArgs e)
{
cnn.ConnectionString= ConfigurationManager.ConnectionStrings["con"].ConnectionString;
if(!IsPostBack)
{
// This will only happen when the page is first loaded, as the first time is not considered a post back, but all others are
dr1 = TableUtoP();
dtWordsList.Load(dr1);
}
}
Only fill the dataTable if it's not a PostBack...
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//TO DO: Make the call to fill the data table here
}
}

datagridview cell edit and save functionality in windows forms?

I'm working on datagridview in c# windows forms application and I'm loading the data from the database, now i want the user to be able to able to edit the cell value and save the value to the database, how to edit the cell value and how can i save the value to the database?
SqlConnection con = new SqlConnection("user id=sa;password=123;database=employee");
SqlDataAdapter da = new SqlDataAdapter("select * from UserReg", con);
DataSet ds = new DataSet();
da.Fill(ds, "p");
dataGridView1.DataSource = ds.Tables["p"];
One of the way to update a database with DataGridView is using of DataGridView's events:
DataGridView.CellBeginEdit
DataGridView.CellValidating
DataGridView.CellEndEdit
Let say: private DataGridView dgv;
Add handlers of events
dgv.CellBeginEdit += dgv_CellBeginEdit;
dgv.CellValidating += dgv_CellValidating;
dgv.CellEndEdit += dgv_CellEndEdit;
private void dgv_CellBeginEdit(Object sender, DataGridViewCellCancelEventArgs e)
{
//Here we save a current value of cell to some variable, that later we can compare with a new value
//For example using of dgv.Tag property
if(e.RowIndex >= 0 && e.ColumnIndex >= 0)
{
this.dgv.Tag = this.dgv.CurrentCell.Value;
//Or cast sender to DataGridView variable-> than this handler can be used in another datagridview
}
}
private void dgv_CellValidating(Object sender, DataGridViewCellValidatingEventArgs e)
{
//Here you can add all kind of checks for new value
//For exapmle simple compare with old value and check for be more than 0
if(this.dgv.Tag = this.dgv.CurrentCell.Value)
e.Cancel = true; //Cancel changes of current cell
//For example used Integer check
int32 iTemp;
if (Int32.TryParse(this.dgv.CurrentCell.Value, iTemp) = True && iTemp > 0)
{
//value is ok
}
else
{
e.Cancel = True;
}
}
Private Sub dgvtest1_CellEndEdit(Object sender, DataGridViewCellEventArgs e)
{
//Because CellEndEdit event occurs after CellValidating event(if not cancelled)
//Here you can update new value to database
}
Try to do this:
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
//after you've filled your ds, on event above try something like this
try
{
da.Update(ds);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I used OleDb but you can use SQL. Here is the code I usually use for the same.
OleDbCommand sCommand;
OleDbDataAdapter sAdapter;
OleDbCommandBuilder sBuilder;
OleDbConnection connection;
DataSet sDs;
DataTable sTable;
string myMode = "";
private void BtnLoad_Click(object sender, EventArgs e)
{
string query = "SELECT * FROM [Table]";
connection = new OleDbConnection(connectionString);
connection.Open();
sCommand = new OleDbCommand(query, connection);
sAdapter = new OleDbDataAdapter(sCommand);
sBuilder = new OleDbCommandBuilder(sAdapter);
sDs = new DataSet();
sAdapter.Fill(sDs, "Table");
sTable = sDs.Tables["Table"];
connection.Close();
DataGrid.DataSource = sTable;
DataGrid.ReadOnly = true;
DataGrid.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
}
private void BtnAdd_Click(object sender, EventArgs e)
{
DataGrid.ReadOnly = false;
myMode = "add";
}
private void BtnEdit_Click(object sender, EventArgs e)
{
DataGrid.ReadOnly = false;
myMode = "edit";
}
private void BtnDelete_Click(object sender, EventArgs e)
{
myMode = "";
if (MessageBox.Show("Do you want to delete this row ?", "Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
DataGrid.Rows.RemoveAt(DataGrid.SelectedRows[0].Index);
sAdapter.Update(sTable);
}
}
private void BtnSave_Click(object sender, EventArgs e)
{
if (myMode == "add")
{
sAdapter.Update(sTable);
MessageBox.Show("Prices Are Successfully Added.", "Saved.", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
}
else if (myMode == "edit")
{
string query = "UPDATE Table_Name SET " +
"Column1 = '" + DataGrid.SelectedRows[0].Cells[0].Value.ToString() + "' ," +
"Column2 = " + DataGrid.SelecteddRows[0].Cells[1].Value.ToString() + ", " +
"WHERE CONDITION";
connection = new OleDbConnection(connectionString);
connection.Open();
sCommand = new OleDbCommand(query, connection);
sAdapter = new OleDbDataAdapter(sCommand);
sBuilder = new OleDbCommandBuilder(sAdapter);
sDs = new DataSet();
sAdapter.Fill(sDs, "Table");
sTable = sDs.Tables["Table"];
connection.Close();
DataGrid.DataSource = sTable;
DataGrid.ReadOnly = true;
}
}
Have a look at the DataGridView Events list. You need to subscribe to the appropriate event, and handle it accordingly. Namely, you're interested in DataGridView.CellValueChanged.
dataGridView1.CellValueChanged += ValueChangedHandler;
private void ValueChangedHandler(object sender, DataGridViewCellEventArgs e) {
// do what is appropriate here.
}
Add this line of code to enable editing on datagridview
dtg.EditMode = DataGridViewEditMode.EditOnKeystroke;
Then use below event
private void dtg_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex > -1 && e.RowIndex > -1)
{
dtg.ReadOnly = false;
}
}
The above two events will enable editing in datagridview.
Then use below event to save the updated data back to db.
private void dtg_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
}

Categories

Resources