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();
}
Related
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;
.....
}
I have a datatable that I fill with data
DataTable data = new DataTable();
FillData(data);
The datatable gets modified on the go and I capture the modified data so I can save it in a DB:
DataTable changes = data.GetChanges();
I use data from the changes DataTable and save it into DB, the query I use returns an INT id that I need to save into the original data DataTable. How can I get corresponding index in the data table basig on the changes table?
I used to intersect to get intersection of data table and changes table
public void intersect(DataTable data, DataTable changes)
{
var changeIds = data.AsEnumerable().Intersect(changes.AsEnumerable(), DataRowComparer.Default);
foreach (DataRow row in changeIds)
{
Response.Write(row["Id"]);
}
}
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);
I am having an datatable which is already populated. Now i want to add few rows to that datatable ,but some of rows might already exist in the datatable.I know its unneccesary but tht is the requirement.
I tried couple of things and got "the row already exist in this table : & this row belongs to some other table" .I also tried importRow ,but i guess it avoid the duplicates by dafault.
Is there any way to do that .If the datatable has 7 rows and i want to add 3 more rows whether its already exist or not. My goal is to send 10 rows to the calling function .
Or is there any other approach altogether?
UPDATE
Using
rowsToAdd.CopyToDataTable(dsCount.Tables[2], LoadOption.PreserveChanges); works but I'm not sure it's the proper way.
You can add new rows in DataTable using code below
DataRow newRow = dataTable.NewRow();
dataTable.Rows.Add(newRow);
To check for any duplicates try
if (table.Rows.Contain(PriKeyTypeValue)) /*See if a Primary Key Value is in
the table already */
continue;
else
table.Row.Add(value1, value2, value3);
If you want to be able to insert duplicate rows but do not want to have an exception thrown set-up your primary key as a unique self-incrementing int then you can insert as many duplicates as you feel like without having to check to see if the table contains that value. Just make sure that it would suffice to have duplicates. There are plenty of examples of setting a primary key just search for it (msdn has at least one). Here is an example:
DataTable table = new DataTable();
table.Columns.Add("Column", typeof(int));
DataColumn column = table.Columns["Column"];
column.Unique = true;
column.AutoIncrement = true;
column.AutoIncrementStep = 1; //change these to whatever works for you
column.AutoIncrementSeed = 1;
table.PrimaryKey = new DataColumn[] { column };
Create a new row using the NewRow() function.
var dataTable = new DataTable();
var dataRow = dataTable.NewRow();
Then add your new row to your datatable
dataTable.Rows.Add(dataRow)
I believe you can use the NewRow() function of the DataTable if you're simply appending a row to the table.
DataTable table = new DataTable();
DataRow row = table.NewRow();
table.Rows.Add(row);
Will that not suffice?
The most straightforward method. After spending a few hours trying everything else.
DataRow dr = ds.Tables[0].NewRow();
dr["ColumnName1"] = "columnvalue"; //string
dr["ColumnName2"] = 123 //int
ds.Tables[0].Rows.Add(dr);
i have a datable and like this i have searched a datarow from the datable on the basis of some primary now i want to add that searched row to another datatable how can i achieve this please let me know
DataTable findRows = (DataTable)ViewState["dt"];
List<int> selectedList=(List<int>)ViewState["selectedList"];
DataTable temp = new DataTable();
foreach (int id in selectedList)
{
DataRow dr=findRows.Rows.Find(id);
}
now i want it to add to datatable temp how can i achieve this?
First, when creating temp don't just instantiate it as a new DataTable but instead call .Clone() on findrows to create a structurally identical DataTable.
Second, use .ImportRow() on the second DataTable and pass it the row from the first DataTable that you'd like to copy. This should create an entirely new row in the second table with the same values as the row from the first table.