i have datagridview that connect to my database (access)
if i stay on any cell and change the value, a see that the value is changed
but when i make refresh i see that the value is back to the original value.
how i can update this cell (without sql query)
i bind dataset to datagridview like this:
dsView = new DataSet();
adp = new OleDbDataAdapter("SELECT * FROM Items", Conn);
adp.Fill(dsView, "Items");
this.dataGridView1.DataSource = dsView.Tables["Items"].DefaultView;
adp.Dispose();
please, i must find how to do it.....
thank's in advance
If your datagridview is connected to the database and you do not want to use SQL, i can suppose it is bound to a datasource. If you performed that through the Visual Studio Designer there should be a TableAdapter (if automatically generated, probably called YOURTABLENAMETableAdapter) and a BindingSource (if automatically generated, probably called YOURTABLENAMEBidingSource).
To update your database you will have to call BindingSource.EndEdit() and then TableAdapter.Update(). After you have done this, you can refresh your data.
EDIT
Now that you have provided better information i can give you a better answer.
In my previous answer, I assumed that you created everything with the designer because you didn't want to use SQL to make the update. Obviously i was wrong.
To achieve what you are looking for, you should use the OleDbCommandBuilder Class which, given a SELECT command, automatically generates simple editing command (insert/update/delete) for your table.
here is an example using your code:
dsView = new DataSet();
adp = new OleDbDataAdapter("SELECT * FROM Items", Conn);
OleDbCommandBuilder cb = new OleDbCommandBuilder(adp);
adp.Fill(dsView, "Items");
this.dataGridView1.DataSource = dsView.Tables["Items"].DefaultView;
//adp.Dispose(); You should dispose you adp only when it is not loger needed (eg: after performing the update)
Now, after you perfomed your changes to the data you can call
adp.Update(dsView, "Items");
Related
I have timer-function. It handles data from sql database every N time (it's doesn't matter actually what time). The subsequent algorithm does not work. Or I don't know how to make it work.
I put data into Dataset.
const string query = "SELECT id FROM SomeTable LIMIT 100";
await using var cmd = new MySqlCommand(query, connection);
var sqlAdapter = new MySqlDataAdapter(cmd);
sqlAdapter.TableMappings.Add("Table", "SomeTable");
sqlAdapter.Fill(_mapping);
_mapping.AcceptChanges();
Where _mapping is dataset.
If this is the first filling of the dataset, then just fill it.
If this is not the first filling, then try to update the data in it. I tried to use sqlAdapter.Update(_mapping). But it doesn't update any data Or I cant get updated data. I tried fill it again and check _mapping.hasChanges(DataRowState.Modified | DataRowState.Added))
But it hasn't any changes.
So how can I fill dataset and catch changed or added rows while I get data from Database?
Or may be I need to use another things like dataTable or something else?
I'm attempting to access a basic table from a local database in my Windows Forms project. I seem to have created the database correctly, and imported the dataset as expected as it displays in my Solution Explorer.
However, I am stuck on how to actually access the data within my database. I've attempted many different solutions but I cannot seem to get anywhere.
Here is what I've accomplished so far:
Solution Explorer Screenshot
But I cannot figure out how to make queries to the dataset, whether it's selecting, updating, or deleting rows.
The closest I've come to getting the data is from the code here:
InventoryDatabaseDataSet context = new InventoryDatabaseDataSet();
var inv = context.Tables["Inventory"];
var all = inv.Select();
But it doesn't return any seemingly valid data.
How do I go about making queries to my dataset? I understand Linq is the common method of making queries, but I don't understand how to get to the point of being able to do such a thing.
Any help would be greatly appreciated, thanks!
The DataSet item in the Solution Explorer represents a number of types. Just as String, Int32 and Form are types, so InventoryDatabaseDataSet is a type. Just like other types, you create an instance in code and then use it.
You will also find that those types that are components have been added to your Toolbox and can be added to forms in the designer, just like other controls and components.
You can also drag items from the Data Sources window and have the designer generate appropriate objects and code. For instance, if you drag a table from the Data Sources window to a form, it will generate a DataSet to store the data, a table adapter to retrieve data from the database and save changes back, a DataGridView to display the data, a BindingSource to link between the DataTable and the DataGridView and a BindingNavigator to navigate the data.
If you do use the designer then you'll see code generated to retrieve data by calling Fill on the table adapter and save changes by calling Update. If you want to do it in code yourself then you can do it something like this to retrieve:
var data = new InventoryDatabaseDataSet();
using (var adapter = new InventoryTableAdapter())
{
adapter.Fill(data);
}
this.InventoryBindingSource.DataSource = data.Inventory;
this.InventoryDataGridView.DataSource = this.InventoryBindingSource;
and this to save:
this.InventoryBindingSource.EndEdit();
var data = (InventoryDataTable) this.InventoryBindingSource.DataSource;
using adapter = new InventoryTableAdapter())
{
adapter.Update(data);
}
After storing data in DataSet,DataSet is read through DataTable object.
Similarly object of DataRow is used to read the row of a table.
Following is the sample code
InventoryDatabaseDataSet ds = new new InventoryDatabaseDataSet();;
DataTable dt = new DataTable();
da.SelectCommand = new SqlCommand(#"SELECT * FROM FooTable", connString);
da.Fill(ds, "FooTable");
dt = ds.Tables["FooTable"];
foreach (DataRow dr in dt.Rows)
{
MessageBox.Show(dr["Column1"].ToString());
}
I have mysql database and there is a table with a name Cars.
I bring Cars table from mysql by using MySqlDataAdapter then fill a datatable.
I use only that datatable to feed the controls that represent a car information on the form and by using a loop I take the next row in this.carsDT. then I feed datagridview source from this data table
MySqlDataAdapter carsMSDA = new MySqlDataAdapter(mysql, conn);
carsMSDA.Fill(this.carsDT);
dataGridViewCars.DataSource = this.carsDT;
The problem is after updatting a row in anothe place of the code, I call again the lines above to make something like refresh or renew this.carsDT. But I find that rows in this.carsDT and dataGridViewCars are doubled for e.g.
if there was 3 rows they will become 6 rows, 3 are the old from previouse state bfore updating a row, and 3 other one of them the updated row.
So I used new datatable like this:
MySqlDataAdapter carsMSDA = new MySqlDataAdapter(mysql, conn);
DataTable carsDT = new DataTable();
carsMSDA.Fill(carsDT);
this.carsDT = carsDT;
//carsMSDA.Fill(this.carsDT);
dataGridViewCars.DataSource = this.carsDT;
I want to notice that after close the form and run again I find it normal and uptaded as it should be.
Is this good idea?
I'am trying to update database after row has been deleted from dataset like this:
SqlCommand mySelectCommand = new SqlCommand("select * from NameDB", c);
SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter(mySelectCommand);
TheNewDataSet ds = new TheNewDataSet();
mySqlDataAdapter.Fill(ds, "NameDB");
DataRow[] FilteredRow = ds.Tables["NameDB"].Select("PName like '" + listBox2.SelectedValue.ToString() + "'");
foreach (DataRow drr in FilteredRow)
{
ds.Tables["NameDB"].Rows.Remove(drr);
}
mySqlDataAdapter.Update(ds, "NameDB");
c.Close();
And nothing happened to database, rows not deleted. According to debugger rows filtered correctly and deleted from DataSet normally. Where is mistake?
Ok, first - it is not the dataset doing updates. NEVER EVER. It is the Adapter. The DataSet does not talk to the database.
But: you dont delete the rows, you - kill them (rows.remove).
http://msdn.microsoft.com/en-us/library/feh3ed13(v=vs.80).aspx
You should not use REMOVE but DELETE, which keeps the row with a status to delete it. THe way you do it you remove it, so the adapter never sees it. With ".Delete" the adpater sees the row as deleted, so it can act upon it.
Looks like you are missing insert/update/delete commands on the sqldataadapter?
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldataadapter.updatecommand.aspx
I ran into a similar problem today at work, so I would like to answer what I understood, so that this could be of some help in the future for others as well as myself.
From what I understood today, .Remove will take the rows of visually from the grid, but would not mark them as the rows to be deleted when you do AcceptChanges to save the changes to the database. As TomTom mentioned, you should use .Delete instead, which will mark those rows as the one's that needs to be deleted when persisting. If you debug your program and see the dataset in visualizer(?), you could see the difference. If I am correct, .Delete will have the rows marked with exclamation, and .Remove, I think just removes.
I have an option to choose between local based data storing (xml file) or SQL Server based.
I already created a long time ago a typed dataset for my application to save data local in the xml file.
Now, I have a bool that changes between Server based version and local version. If true my application get the data from the SQL Server.
I'm not sure but It seems that Sql Adapter's Fill Method can't fill the Data in my existing schema
SqlCommand cmd = new SqlCommand("Select * FROM dbo.Categories WHERE CatUserId = 1", _connection);
cmd.CommandType = CommandType.Text;
_sqlAdapter = new SqlDataAdapter(cmd);
_sqlAdapter.TableMappings.Add("Categories", "dbo.Categories");
_sqlAdapter.Fill(Program.Dataset);
This should fill my data from dbo.Categories to Categories (in my local, typed dataset).
but it doesn't. It creates a new table with the name "Table". It looks like it can't handle the existing schema.
I can't figure it out. Where is the problem?
btw. of course the database request I do isn't very useful that way. It's just a simplified version for testing...
The Fill overload you are using, passing in a DataSet will always create a NEW DataTable in the supplied DataSet with name "Table" (MSDN).
So, I think you either need to change your TableMapping to:
_sqlAdapter.TableMappings.Add("Table", "Categories");
(MSDN) assuming your DataTable name is "Categories".
Or, don't use TableMappings and just supply the second argument - the name of the DataTable in that DataSet you want to populate (MSDN). The approach I usually use is actually to pass the DataTable itself that you want to populate, instead of the DataSet (MSDN).
Try _sqlAdapter.TableMappings.Add("Table", "Categories");, but as i remember you will have to add column mapping also. btw, you can try to create typed dataadapter, it is useless thing, but you can take mapping from there.