DataTable with existing Schema not Importing DataRow of same Schema - c#

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);

Related

ADO.NET DataTable sort does not reflect in containing DataSet

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;
.....
}

How to find the differences between two queries identical in structure that have been read into DataTables? Return the changed values

What I am looking to do is query a database and then do a comparison against a past query from the same database table that has been saved into XML. I thought that I would be able to do this with DataTables, but it looks like they will not have this functionality.
I attempted to read the XML file into a DataSet then use this method.
public DataTable compareSets(DataTable today, DataTable yesterday)
{
today.Merge(yesterday);
DataTable d3 = yesterday.GetChanges();
return d3;
}
But this just returned everything. What I am looking for is to get values that were changed from one day to the next inside the database table.
get values that were changed
The key(s) of the rows that have changed? And also the columns that are different for each row?
What you're after needs further definition. You could also pull this off without leaving the database if you save the outcome of your query into a table. Then you could "select rowkey from june join july on june.whoID = july.whoID where june.importantColumn <> july.importantColumn" superfast.
I solved my issue by declaring the primary key. This allowed the comparison to return the values that had changed. I also ended up having to write both files to XML before the comparison as it was giving an type mismatch error.
public DataTable compareConfigs(DataTable today, DataTable yesterday)
{
DataTable dtCurrent = today;
DataTable dtLast = yesterday;
dtLast.AcceptChanges();
DataTable dtChanges = null;
dtLast.Merge(dtCurrent, true);
dtChanges = dtLast.GetChanges(DataRowState.Unchanged);
return dtChanges;
}
static void Main(string[] args)
{
// Declaring the DataSets
DataSet dataSet = new DataSet();
DataSet dataSet2 = new DataSet();
// reading in an XML file to DataTable
dataSet.ReadXml(#"Path to saved XML query");
DataTable yesterday = dataSet.Tables[0];
yesterday.PrimaryKey = new DataColumn[] { yesterday.Columns["Key"]};
// reading in an xml file to datatable
dataSet2.ReadXml(#"Path to saved XML query");
DataTable today = dataSet2.Tables[0];
today1.PrimaryKey = new DataColumn[] { today1.Columns["Key"]};
ConfigCompare comp = new ConfigCompare();
DataTable mismatch = comp.compareConfigs(today, yesterday);
}
}

Update a single row in DataTable

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();
}

how to add new datatable to dataset at first position

i have one dataset with 3 data tables again i have to add one more data table in same dataset at first position(Ex:mydataset.tables[0]th position) .can any one help me regarding this.
You will probably need to pull all the datatables out of the dataset into a list, get them in the right order, and then re-add them all to the dataset since you cannot insert to or modify the existing order:
var tables = new DataTable[4];
tables[0] = mynewtable;
tables[1] = mydataset.Tables[0];
tables[2] = mydataset.Tables[1];
tables[3] = mydataset.Tables[2];
mydataset.Tables.Clear();
mydataset.Tables.Add(Tables[0]);
mydataset.Tables.Add(Tables[1]);
mydataset.Tables.Add(Tables[2]);
mydataset.Tables.Add(Tables[3]);

Replace a DataTable in a DataSet

-Changed the question into a different simpler form-
Please review this piece of code :
"Given Error"
Error :
Update unable to find TableMapping['Table'] or DataTable 'Table'.
The DataSet is Strongly typed,
We have a DataTable "dtNew"
[Made from a list "ListProducts", (No matter here !)]
one column's name in the database differs from the list's field :
"Title" should mapped with the column : "TitleInDb"
SqlCeDataAdapter Adapter;
DsProducts Ds1Products ; // Strongly Typed
DataTable dtNew = new DataTable("Products");
DataColumn dc;
DataRow[] updRows;
// Fields : Name , Title, Price
dc = new DataColumn("Name", typeof(string));
dtNew.Columns.Add(dc);
dc = new DataColumn("TitleInDb", typeof(string)); // The difference is by a reason
dtNew.Columns.Add(dc);
dc = new DataColumn("Price", typeof(string));
dtNew.Columns.Add(dc);
dtNew = updRows.CopyToDataTable();
Ds1Products.Tables.Add(dtNew);
// The Problems appear here :
// The Iteration is just for debugging phase and watching the changes which the columns are same
as before
foreach (var col in dtNew.Columns)
{
Console.WriteLine(col.ToString());
Console.WriteLine(col.GetType());
}
// New Table is there, But here will come the Error
Adapter.Update(Ds1Products);
Running this, Iterating through the new columns I see that there is no change to the "Products" table which I thought should have been deleted at that time. Also the name of the new table "dtNew" seems to be "table1"
Additional Notes :
It uses Sql Compact 3.5
The code is just a piece of code, Showing the exact problem !
please review the code and give your ideas on this,
I'm trying to make the whole database based on a refreshed Table (or DataRows[] )
Edit :
*Replace a DataTable in a DataSet :*
It means remove the first DataTable and Create new one and place it in !
Couldn't say easier ... (Based on a comment)

Categories

Resources