I have created a data table. It has 3 column Product_id, Product_name and Product_price
Datatable table= new DataTable("Product");
table.Columns.Add("Product_id", typeof(int));
table.Columns.Add("Product_name", typeof(string));
table.Columns.Add("Product_price", typeof(string));
table.Rows.Add(1, "abc", "100");
table.Rows.Add(2, "xyz", "200");
Now I want to find by index, and update that row.
say for e.g.
I want to change value of Product_name column to "cde" that has the Product_id column value : 2.
First you need to find a row with id == 2 then change the name so:
foreach(DataRow dr in table.Rows) // search whole table
{
if(dr["Product_id"] == 2) // if id==2
{
dr["Product_name"] = "cde"; //change the name
//break; break or not depending on you
}
}
You could also try these solutions:
table.Rows[1]["Product_name"] = "cde" // not recommended as it selects 2nd row as I know that it has id 2
Or:
DataRow dr = table.Select("Product_id=2").FirstOrDefault(); // finds all rows with id==2 and selects first or null if haven't found any
if(dr != null)
{
dr["Product_name"] = "cde"; //changes the Product_name
}
You can find that row with
DataRow row = table.Select("Product_id=2").FirstOrDefault();
and update it
row["Product_name"] = "cde";
Try the SetField method:
By passing column object :
table.Rows[rowIndex].SetField(column, value);
By Passing column index :
table.Rows[rowIndex].SetField(0 /*column index*/, value);
By Passing column name as string :
table.Rows[rowIndex].SetField("product_name" /*columnName*/, value);
If your data set is too large first select required rows by Select(). it will stop further looping.
DataRow[] selected = table.Select("Product_id = 2")
Then loop through subset and update
foreach (DataRow row in selected)
{
row["Product_price"] = "<new price>";
}
You can traverse through the DataTable like below and set the value
foreach(DataTable thisTable in dataSet.Tables)
{
foreach(DataRow row in thisTable.Rows)
{
row["Product_name"] = "cde";
}
}
OR
thisTable.Rows[1]["Product_name"] = "cde";
Hope this helps
Try this I am also not 100 % sure
for( int i = 0 ;i< dt.Rows.Count; i++)
{
If(dt.Rows[i].Product_id == 2)
{
dt.Rows[i].Columns["Product_name"].ColumnName = "cde";
}
}
try this,
foreach(DataRow rw in dt.Rows)
{
rw["Obj_Amt"] = h.Decrypt(rw["Obj_Amt"].ToString());
dt.AcceptChanges();
rw.SetModified();
}
use SetModified() method to update data table value.
Related
I am creating a datatable with 3 columns as below and pushing the values into it from a while loop. Once the while loop is completed. I want to extract the validation values which are True or False and apply a condition to that, which will be like if all the values are "True" then I should get an output "True" if anyone of them is "False" I should get "False" value as output.
DataTable table = new DataTable(); table.Columns.Add("Id", typeof(int));
table.Columns.Add("Number", typeof(string));
table.Columns.Add("Validation", typeof(string));
For getting values of column Validation I am using the code below, but not sure how to apply the above condition and get final value.
DataView dv = new DataView(table);
DataTable dt = dv.ToTable(true, "Validation");
You can use the below code to iterate the datatable and check the value of each row.
foreach (DataRow dtRow in dtTable.Rows)
{
// On all tables' columns
foreach(DataColumn dc in dtTable.Columns)
{
var field1 = dtRow[dc].ToString();
}
}
This is what I used and the above issue was resolved. Added the reference for System.Data.DataSetExtensions.
string validationstr = "False";
bool Contains = table.AsEnumerable().Any(row => validationstr == row.Field<string>("Validation"));
if (Contains == true)
{
}
else
{
}
I have a DataTables with Emails. Over the LDAP I have the Userdata. Now Id like to Increase the DataTable depending upon the EmailAdress.
myDataTable.Columns.Add(new DataColumn("LDAP_Data"));
foreach(DataRow row in modiTable.Rows)
{
string myLDAPData = DoLDAPAction(row.Field<string>("EMAIL"));
//how to insert to myDataTable > LDAP_Data
}
how can I insert the new Data from LDAP to the new Column?
Thanks
If you add a row to a DataTable you have to add a row which columns match you table. This is why you get back a row if you call DataTable.Add().
Here an example how to add new rows:
static void Main(string[] args)
{
DataTable dt = new DataTable(); // Create a example-DataTable
dt.Columns.Add(new DataColumn() { ColumnName = "Name", DataType = typeof(string) }); // Add some columns
dt.Columns.Add(new DataColumn() { ColumnName = "Id", DataType = typeof(int) });
// Let's fill the table with some rows
for (int i = 0; i < 20; i++) // Add 20 Rows
{
DataRow row = dt.Rows.Add(); // Generate a row
row["Id"] = i; // Fill in some data to the row. We can access the columns which we added.
row["Name"] = i.ToString();
}
// Let's see what we got.
for (int i = 0; i < dt.Columns.Count; i++) // Loop through all columns
{
Console.Write(dt.Columns[i].ColumnName + ";"); // Write the ColunName to the console with a ';' a seperator.
}
Console.WriteLine();
foreach (DataRow r in dt.Rows) // Generic looping through DataTable
{
for (int i = 0; i < dt.Columns.Count; i++) // Loop through all columns
{
Console.Write(r[i] + ";");
}
Console.WriteLine();
}
}
You can do it by using the NewRow method:
foreach(DataRow row in modiTable.Rows)
{
string myLDAPData = DoLDAPAction(row.Field<string>("EMAIL"));
DataRow row = modiTable.NewRow();
row["EMAIL"] = myLDAPData;
//You might want to specify other values as well
}
Or you can use the Add() method, as suggested in kara's answer.
myDataTable.Columns.Add(new DataColumn("LDAP_Data"));
foreach(DataRow row in modiTable.Rows)
{
string myLDAPData = DoLDAPAction(row.Field<string>("EMAIL"));
var row = myDataTable.NewRow()
row["LDAP_Data"] = YOUR_DATA;
myDataTable.Rows.Add(row);
}
I have a DataTable binding to a WPF datagrid where I've created columns and created a set number of rows, with the first column populated with default values in each row. It looks like this table:
So I have the Size column and all its values and the headers for each column. Now I need to input the data I collected into my DataTable but not using the indexes for columns and rows, I need to find the cell item using the header titles for row and column. Here's what I have:
heatMapTbl.Rows['2000000']['BOA'] = statVal;
Any suggestions?
Hint:
DataTable table = new DataTable();
var myColumn = table.Columns.Cast<DataColumn>().SingleOrDefault(col => col.ColumnName == "myColumnName");
if (myColumn != null)
{
// just some roww
var tableRow = table.AsEnumerable().First();
var myData = tableRow.Field<string>(myColumn);
// or if above does not work
myData = tableRow.Field<string>(table.Columns.IndexOf(myColumn));
}
I looped through the rows like this:
foreach (DataRow row in LiqTbl.Rows)
{
if (row.ItemArray[0].Equals(timezone))
{
foreach (DataColumn column in LiqTbl.Columns)
{
if (column.ColumnName.Equals(lp))
{
//Write the value in the corresponding row
row[column] = liq.ToString("N", CultureInfo.InvariantCulture);
}
}
}
}
I have created 3 datatables
var dt1= new DataTable();
var dt2= new DataTable();
var dt3= new DataTable();
Then i loop
foreach (DataRow row1 in dt1.Rows)
{
dt3.Rows.Add(row1.ItemArray);
foreach (DataRow row2 in dt2.Rows)
{
var Id2 = row1["Id"];
var Id1= row2["Id"];
if (Id1 == Id2)
{
dt3.rows["Name"] = "" ; // doesnt work
}
}
}
As you can see that i loop on 2 datatables. Then in inner loop i check if the records matches. Now if the record matches then i want to update column "Name" on dt3 datatable.
I tried using
dt3.rows["Name"] = "" ;
But this doesnt work. I know the reason that its because i again need to loop on dt3 datatable and
assign values to column in that loop. But not sure how to do it and if there is even more better solution. I mean we can find id in dt3 datatable and then update value. But not sure how to do it
Is there more intelligent solution than looping on 2 table?
The first foreach is not needed. A simple DataTable.Copy will bring all the data and structure from the original table in the destination table. Then looping on the second table and Select on the third to find the matching rows and clear the name.
dt3 = dt1.Copy();
foreach (DataRow row2 in dt2.Rows)
{
DataRow[] match = dt3.Select("ID=" + row2["ID"].ToString());
if(match.Lenght > 0)
match[0]["Name"] = "" ;
}
Not sure if this is more performant from the other answers. Need to be tested
dt3.rows doesn't work, you want to change the name of the row that you have added now. This should work:
foreach (DataRow row1 in dt1.Rows)
{
DataRow newRow = dt3.Rows.Add(row1.ItemArray);
foreach (DataRow row2 in dt2.Rows)
{
var Id2 = row1["Id"];
var Id1 = row2["Id"];
if (Id1 == Id2)
{
newRow["Name"] = "new Name";
}
}
}
Try this:
foreach (DataRow row1 in dt1.Rows)
{
var row = dt3.Rows.Add(row1.ItemArray);
foreach (DataRow row2 in dt2.Rows)
{
var Id2 = row1["Id"];
var Id1= row2["Id"];
if (Id1 == Id2)
{
row["Name"] = ""; //maybe works
}
}
}
How about,
dt2Lookup = new HashSet(
dt2.AsEnumerable().Select(row => row.Field<int>("Id")));
dt3 = dt1.Clone();
forreach (var row In dt1.AsEnumerable())
{
var newRow = dt3.Rows.Add(row.ItemArray)
if (dt2lookup.Contains(row.Field<int>("Id"))
{
newRow.SetField("Name", string.Empty);
}
}
The HashSet should provide good lookup performance.
dt3 = dt1.Copy();
var RowDictionary = dt3.Rows.OfType<DataRow>().ToDictionary(dr => dr["ID"].ToString());
//replace by Dictionary<string,List<DataRow>> in case ID is not unique and fill it with a foreach loop.
foreach (DataRow row2 in dt2.Rows)
{
DataRow Match;
if (c.TryGetValue(row2["ID"].ToString(), out Match))
{
Match["Name"] = "";
}
}
You should call:
dt3.rows[dt3.rows.Count - 1].Columns["Name"] = "" ;
I am looping through a datatable and currently I do
string customerId = row["CustomerId"].ToString();
string companyName = row["Company Name"].ToString();
Instead of declaring every variable how do I add these do a dictionary?
I was thinking something like:
foreach (DataRow row in customerTbl.Rows)
{
Dictionary<string, string> customerDictionary = new Dictionary<string, string>();
customerDictionary.Add(row[].ToString(), row[].ToString());
so yeah, how do I get the row name and value into there?
Thanks in advance.
EDIT:
I guess I didn't give you all information about what I am trying to do.
I query a database for a customer and populate a datatable with about 50 columns, I use the customer id to query another database and get the same customer from there. I then want to compare all 50 fields from both databases for the same customer and check if any field is different. I thought I could add the column name with the value in a dictionary for each row for each customer and then with two loops check if the values for the same key (column name) differs, is this a totally wrong approach?
having an if (customerId1 != customerId2 || customerName1 != customerName2 || and so on for 50 fields is not very good.
Are you looking for a generic solution to this kind of thing? If so does your DataTable always contain 2 columns where the first can be treated as the dictionary key and the second the value? If so, then simply use the column index instead of the column name
var customerDictionary = new Dictionary<string, string>();
foreach (DataRow row in customerTbl.Rows)
customerDictionary.Add(row[0].ToString(), row[1].ToString());
If the values in the customerId and CompanyName columns are never null then instead of using ToString(), you can cast the values to a string
customerDictionary.Add((string)row[0], (string)row[1]);
FYI, the DataTable has a search capability as well (the Find() method). If you set up a primary key column the search will be extremely fast and you may not need to copy the data from a DataTable to a Dictionary.
Edit : A complete working example of one way of doing this in C# code as per the OPs edited question
class Program
{
static void Main(string[] args)
{
var table1 = GetCustomersFromFirst();
var table2 = GetCustomersFromSecond();
foreach (DataRow row in table1.Rows)
{
var foundRows = table2.Select("CustomerId = " + (string)row[0]);
if (foundRows.Length == 1)
{
var foundRow = foundRows[0];
foreach (DataColumn col in table1.Columns)
{
var valueOfColumnFromTable1 = row[col.Ordinal].ToString();
var valueOfColumnFromTable2 = foundRow[col.Ordinal].ToString();
if (String.Compare(valueOfColumnFromTable1, valueOfColumnFromTable2) != 0)
{
//the colum values are not the same.
}
}
}
else
{
// Something is wrong since more than one matching record was found
// or no matching records were found.
}
}
}
static DataTable GetCustomersFromFirst()
{
var dt = GetInitializedCustomerDataTable();
var row = dt.NewRow();
row[0] = "1";
row[1] = "CompanyA";
dt.Rows.Add(row);
row = dt.NewRow();
row[0] = "2";
row[1] = "CompanyB";
dt.Rows.Add(row);
row = dt.NewRow();
row[0] = "3";
row[1] = "CompanyC";
dt.Rows.Add(row);
return dt;
}
static DataTable GetCustomersFromSecond()
{
var dt = GetInitializedCustomerDataTable();
var row = dt.NewRow();
row[0] = "1";
row[1] = "CompanyA";
dt.Rows.Add(row);
row = dt.NewRow();
row[0] = "2";
row[1] = "CompanyD";
dt.Rows.Add(row);
row = dt.NewRow();
row[0] = "3";
row[1] = "CompanyC";
dt.Rows.Add(row);
return dt;
}
static DataTable GetInitializedCustomerDataTable()
{
var dt = new DataTable();
dt.Columns.Add("CustomerId", typeof(string));
dt.Columns.Add("CompanyName", typeof(string));
return dt;
}
}
In the test data, the 2nd row does not match. So it should fall into the condition where the comment says:
//the colum values are not the same.
Personally, I'd look at doing this in the database itself.
Try this.
Dictionary<string, string> customerDictionary = new Dictionary<string, string>();
foreach (DataRow row in customerTbl.Rows)
{
if(row["CustomerId"] != null && customerDictionay.ContainsKey("CustomerId") == false)
{
customerDictionary.Add(row["CustomerID"].ToString(), row["CompanyName"] as string);
}
}
Just a question, what's the benefit of putting the values in a dictionary? You are basically just eliminating the need of writing .ToString() when accessing the values...i.e, instead of:
row["CustomerID"].ToString();
you write
customerDictionary["CustomerID"];
Or have I missed something?