I want to sort a DataTable within a DataSet. I have the following code:
DataTable dt = ds.Tables[0];
dt.TableName = "NEWNAME";
dt.DefaultView.ApplyDefaultSort = false;
dt.DefaultView.Sort = "COL1 desc";
dt = dt.DefaultView.ToTable();
dt.AcceptChanges(); // <-- Break Point Here
ds.AcceptChanges();
As I step through the code beyond the break point in Visual Studio, checking on dt in VS visualizer shows the sorted table, but then checking on ds in VS visualiser does not show the table data in sorted order, even though the name change is reflected. I have tried multiple ways of sorting the datatable available in a google search but the outcome remains the same.
What am I doing wrong?
DefaultView.Sort doesn't sort anything. It is just a string that will be used when you require the construction of a new table like you do in the line
dt = dt.DefaultView.ToTable();
after this point the dt reference (correctly sorted with the info taken from DefaultView.Sort) is no more pointing to the ds.Tables[0]. It is an entirely new DataTable.
The other way in which the DefaultView.Sort applies is when you loop through the DefaultView like in
foreach(DataViewRow dvr in ds.Tables[0].DefaultView)
{
// Here you get a row from the table sorted according to the property.
DataRow row = dvr.Row;
.....
}
One DataSet usually has lots of DataTable, but I'm only to target a particular DataTable which I thought it's pretty normal but apparently failed to do it?
Below were the approaches I've tried:
//Could not find an implementation of the query pattern for source type.......
DataTable dt = from table in changesDataSet.Tables
where table.TableName = "ABC"
select table;
//Surprisingly there was no method "Where" in changesDataSet.Tables
DataTable dt = changesDataSet.Tables.Where(x=>x.TableName="ABC").First();
Below was the code that able to print each and every table. I know I can do it via a loop but please tell me loop isn't the only options
foreach(DataTable table in changesDataSet.Tables)
{
Console.WriteLine(table.TableName);
}
You can access the table using an indexer on the collection of tables (DataTableCollection):
DataTable dt = changesDataSet.Tables["ABC"];
Greets! I am having problems importing a row I created into a DataTable that resides in a DataSet. I pre-populate the "newDataSet" from a SQL Database that is empty but it does contain Tables with a Schema already set up. I have verified that the DataTables in "newDataSet" are getting the Schema imported to them.
Everything looks right as there is no error logs, but no datarow is ever added. Both my Console.WriteLine report back the same Count.
Thank you for taking the time to review this. I appreciate you.
Initial Setup:
var DataSet newDataSet = new DataSet("foo"); // A SQL Adapater was used to fill this from a pre existing Database.
var checkDataSet = new DataSet();
var checkDataTable = new DataTable();
Cloning the DataSet and DataTable.
checkDataSet = newDataSet.Clone();
checkDataTable = checkDataSet.Tables["moreFoo"].Clone();
Creating the DataRow:
var newDataRow = checkDataTable.NewRow();
Filling the Columns in the DataRow:
newDataRow[0] = obj1;
newDataRow[1] = obj2;
newDataRow[2] = obj3;
Importing the DataRow to the "newDataSet" DataTable:
Console.WriteLine(newDataSet.Tables["moreFoo"].Rows.Count.ToString());
newDataSet.Tables["moreFoo"].ImportRow(newDataRow);
Console.WritelLine(newDataSet.Tables["moreFoo"].Rows.Count.ToString());
The answer is:
newDataSet.Tables["moreFoo"].ImportRow(newDataRow);
should be:
newDataSet.Tables["moreFoo"].Rows.Add(newDataRow.ItemArray);
tl;dr:
I want to update ONE DataTable row and then re-cache this whole DataTable(The DataTable not just the row) so I can use it later on
I'm using a cache to store a large DataTable that I've filled with a SqlAdapter based on my MSSQL database
I use this cache to get the DataTable then use it to display a table inside a webpage, nothing odd here.
But this DataTable contains a list of users and I want to be able to edit these users(edit them in the MSSQL database that is) which is easy to do.
The issue is that after each SQL Update you have to re-cache the DataTable(otherwise it'll only be updated in the database but not in the DataTable/webpage) and since it is very large it's very annoying and makes the very simple user update take a very long time since it'll also have to a SQL SELECT to get all posts and then re-cache it
Because of this I want to update that specific row in the DataTable directly after doing my SQL update, this way I don't have to re-fetch the whole SQL table (It is the SQL SELECT part that takes a while since it is so large)
So far I've done this
//We just updated our user, now we'll fetch that with SQL and put it in a new fresh DataTable(that contains just that one row) - since this is much faster than getting the whole table
//Then we'll use that DataTable containing one fresh row to update our old DataTable and re-cache it
DataTable newDataTable = getUserByID(userID); //Get our just edited DataTable row
DataTable cachedDataTable = getSetUserCache(); //Get our cached DataTable
DataRow oldRow = cachedDataTable.Select(string.Format("id = {0}", userID)).FirstOrDefault(); //Get the old row that contains the correct ID
string test = oldRow["status"].ToString(); //Contains the old and cached value before it got edited
oldRow = newDataTable.Rows[0]; //Update the old row with the new row
string test2 = oldRow["status"].ToString(); //Now it contains the new edited value
//Here I should update the cachedDataTable with the new row updated row
DataRow oldRowAfterUpdated = cachedDataTable.Select(string.Format("id = {0}", userID)).FirstOrDefault(); //Get the old row that now should be updated but isn't
string test3 = oldRowAfterUpdated["status"].ToString(); //Still contains the old and cached value before it got edited
success = updateUserCache(cachedDataTable); //Update the DataTable cache that we'll be using later on
I only see posts on how you update the rows, but how do you actually update the DataTable itself with the new row?
Solution :
cachedDataTable.Select(string.Format("id = {0}", userID)).FirstOrDefault().ItemArray = newDataTable.Rows[0].ItemArray;
I think that you may use ItemArray property of DataRow:
void Main()
{
DataTable tableOld = new DataTable();
tableOld.Columns.Add("ID", typeof(int));
tableOld.Columns.Add("Name", typeof(string));
tableOld.Rows.Add(1, "1");
tableOld.Rows.Add(2, "2");
tableOld.Rows.Add(3, "3");
DataTable tableNew = new DataTable();
tableNew.Columns.Add("ID", typeof(int));
tableNew.Columns.Add("Name", typeof(string));
tableNew.Rows.Add(1, "1");
tableNew.Rows.Add(2, "2");
tableNew.Rows.Add(3, "33");
tableOld.Rows[2].ItemArray = tableNew.Rows[2].ItemArray; //update specific row of tableOld with new values
//tableOld.Dump();
}
I have a table which has some 100-200 records.
I have fetch those records into a dataset.
Now i am looping through all the records using foreach
dataset.Tables[0].AsEnumerable()
I want to update a column for each record in the loop. How can i do this. Using the same dataset.
I'm Assumng your using a Data Adapter to Fill the Data Set, with a Select Command?
To edit the data in your Data Table and save changes back to your database you will require an Update Command for you Data Adapter. Something like this :-
SQLConnection connector = new SQLConnection(#"Your connection string");
SQLAdaptor Adaptor = new SQLAdaptor();
Updatecmd = new sqlDbCommand("UPDATE YOURTABLE SET FIELD1= #FIELD1, FIELD2= #FIELD2 WHERE ID = #ID", connector);
You will also need to Add Parameters for the fields :-
Updatecmd.Parameters.Add("#FIELD1", SQLDbType.VarCHar, 8, "FIELD1");
Updatecmd.Parameters.Add("#FIELD2", SQLDbType.VarCHar, 8, "FIELD2");
var param = Updatecmd.Parameters.Add("#ID", SqlDbType.Interger, 6, "ID");
param.SourceVersion = DataRowVersion.Original;
Once you have created an Update Command with the correct SQL statement, and added the parameters, you need to assign this as the Insert Command for you Data Adapter :-
Adaptor.UpdateCommand = Updatecmd;
You will need to read up on doing this yourself, go through some examples, this is a rough guide.
The next step is to Enumerate through your data table, you dont need LINQ, you can do this :-
foreach(DataRow row in Dataset.Tables[0].Rows)
{
row["YourColumn"] = YOURVALUE;
}
One this is finished, you need to call the Update() method of yout Data Adapter like so :-
DataAdapter.Update(dataset.Tables[0]);
What happens here, is the Data Adapter calls the Update command and saves the changes back to the database.
Please Note, If wish to ADD new rows to the Database, you will require am INSERT Command for the Data Adapter.
This is very roughly coded out, from the top of my head, so the syntax may be slightly out. But will hopefully help.
You should use original DataAdapter (adapter in code below) that was used to fill DataSet and call Update method, you will need CommandBuilder also, it depends what DB you are using, here is the example for SQL server :
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
adapter.UpdateCommand = builder.GetUpdateCommand();
adapter.Update(dataset);
dataset.AcceptChanges();
Here is the good example :
http://support.microsoft.com/kb/307587
The steps would be something like:
- create a new DataColumn[^]
- add it to the data table's Columns[^] collection
- Create a DataRow [^] for example using NewRow[^]
- Modify the values of the row as per needed using Item[^] indexer
- add the row to Rows[^] collection
- after succesful modifications AcceptChanges[^]
Like this:
DataTable table = new DataTable();
table.Columns.Add("ID", typeof(int));
table.Columns.Add("ProductName");
table.Rows.Add(1, "Chai");
table.Rows.Add(2, "Queso Cabrales");
table.Rows.Add(3, "Tofu");
EnumerableRowCollection<DataRow> Rows = table.AsEnumerable();
foreach (DataRow Row in Rows)
Row["ID"] = (int)Row["ID"] * 2;
Add the column like below.
dataset.Tables[0].Columns.Add(new DataColumn ("columnname"));
Update the columns values like below.
for (int i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
dataset.Tables[0].Rows[i]["columnname"] = "new value here";
}
Update Database
dataset.AcceptChanges();