var itemAmountList = _itemAmountvalue.Split(',');
var listItemDescriptionValues = _itemDescriptionvalue.Split(',');
IEnumerator enum1 = itemAmountList.GetEnumerator();
IEnumerator enum2 = listItemDescriptionValues.GetEnumerator();
DataTable dtCustomInvoiceDetail = new DataTable();
dtCustomInvoiceDetail.Columns.Add("purchaseOrderID");
dtCustomInvoiceDetail.Columns.Add("itemAmount");
dtCustomInvoiceDetail.Columns.Add("itemDescription");
while ((enum1.MoveNext()) && (enum2.MoveNext()))
{
var description = enum1.Current;
var amount = enum2.Current;
DataRow dr = dtCustomInvoiceDetail.NewRow();
dr["itemDescription"] = description;
dr["itemAmount"] = amount;
dr["purchaseOrderID"] = strPoid;
}
Above is the code that I am using to iterate through a list and populate a datatable.
I do not see any rows added to the datatable
Verified the data and looks good
it iterates through the loop the no of times as required
But still do not see any data in the datatable
In your code
DataRow dr = dtCustomInvoiceDetail.NewRow();
does not actually add a row to the table, it only creates a table row with the correct columns. In order to add the row you need to call
dtCustomInvoiceDetail.Rows.Add(dr)
at the end
the problem is that you are not adding the generated row to datatable.
Datatable.NewRow :
You must use the NewRow method to create new DataRow objects with
the same schema as the DataTable. After creating a DataRow, you
can add it to the DataRowCollection, through the DataTable
object's Rows property
you should add the row to your datatable like this
dtCustomInvoiceDetail.Rows.Add(dr);
also note that you can convert the whole enumerator logic to a simple for loop, it has more readability and less overhead
for (int i = 0; i < Math.Min(itemAmountList.Count, listItemDescriptionValues.Count); i++)
{
var description = itemAmountList[i];
var amount = listItemDescriptionValues[i];
DataRow dr = dtCustomInvoiceDetail.NewRow();
dr["itemDescription"] = description;
dr["itemAmount"] = amount;
dr["purchaseOrderID"] = strPoid;
}
also it seems that there is an inconsistency between names and variable assignments. you assign a value from listItemDescriptionValues to amount variable and from itemAmountList to description. Please double check it.
Related
Update: even though I have got the required result but when the the second function access the data table the value is still the same
It a sequential program with two functions in different classes. First sort and second replace function. So it should sort the value and other function should be able to retrieve the sorted table but when it retrieve the datatable it gives the unsorted table.
I have used acceptchanges() but it also give the same result.
The program is trying to sort the table according to the required field and the result is stored in Sorted table variable. I am trying to copy this to the original i-e sourceTables but it is not working and is adding another row instead of updating [As shown in below dig]. I have tried to copy whole table but it does not work and by adding rows it is not giving the required result. I have used different methods but I am not getting the required result.
List<DataTable> sourceTables = context.GetDataByTable(sourceTable.StringValue);
List<DataTable> targetTables = context.GetDataByTable(targetTable.StringValue, sourceTables.Count);
string orderDesc= orderField.StringValue + " DESC";
for (int i = 0; i < sourceTables.Count; i++)
{
DataView dv = sourceTables[i].DefaultView;
if (orderDirection.StringValue == OrderDirectionAsc)
{
// for Sorting in Ascending Order
dv.Sort = orderField.StringValue;
}
else
{
// for Sorting in Descending Order
dv.Sort = orderDesc;
}
DataTable sortedTable = dv.ToTable();
DataTable dttableNew = sortedTable.Clone();
//sourceTables[i] = sortedTable.Copy();
//targetTables[i] = dv.ToTable();
//targetTables[i] = sortedTable.Copy();
// foreach (DataRow dr in sortedTable.Rows)
//// targetTables[i].Rows.Add(dr.ItemArray);
//}
for (int j = 0; j < sourceTables[i].Rows.Count; j++)
{
if (sourceTable.GetValue().ToString() == targetTable.GetValue().ToString())
{
foreach (DataRow dr in sortedTable.Rows)
{
targetTables[i].Rows.Add(dr.ItemArray);
}
else
{
foreach (DataRow dr in sortedTable.Rows)
{
targetTables[i].Rows.Add(dr.ItemArray);
}
// targetTables[i] = sortedTable.Copy(); does not work
//foreach (DataRow drtableOld in sortedTable.Rows)
//{
// targetTables[i].ImportRow(drtableOld);
//}
Instead of replacing the first values it is adding more rows
any help would be appreciated
If any one have problem with duplicate data or the changes are only local and is not effecting the original data table. Remember to always use .ImportRow(dr) function to add rows to the table and if you use Tables[i].Rows.Add(dr.ItemArray); the changes will affect only the local table and not the original one. Use .clear to remove the old rows from the orginal table. The action done directly on the original function will only effect the rows. If it is done on the clone copy changes will nor affect the original table.
Here is the complete code
DataTable sortTable = dv.ToTable();
if (sTable.GetValue().ToString() == tTable.GetValue().ToString())
{
sTables[i].Clear();
foreach (DataRow dr in sortTable.Rows)
{
sTables[i].ImportRow(dr);
}
sTables[i].AcceptChanges();
}
The situation is this. I've got a select query that gets and array of DataRows that I want to insert into a new DataTable.
But when trying to add the Row I get the following error:
"Row already belongs to another Table".
So I tried creating and initializing a new DataRow within the loop(for and foreach loop) then throw an error when initializing the DataRow:
"Inaccessible due to its protection level"
Any Ideas? Feels like I'm missing something silly.
My Code for the first Error:
var DRCurrentAuspragung = _DTAuspragung.Select(#"MerkmalID = "+Convert.ToString(MerkmalID));
_DTCurrentAuspragung = new DataTable();
for (int i = 0; i < DRCurrentAuspragung.Length;i++ )
{
DataRow RowAdd = DRCurrentAuspragung[i];
_DTCurrentAuspragung.Rows.Add(RowAdd);
}
And for the second error:
var DRCurrentAuspragung = _DTAuspragung.Select(#"MerkmalID = "+Convert.ToString(MerkmalID));
_DTCurrentAuspragung = new DataTable();
foreach (DataRow dr in DRCurrentAuspragung)
{
DataRow RowAdd = new DataRow();
RowAdd = dr;
_DTCurrentAuspragung.Rows.Add(RowAdd);
}
Thanks in advance.
The reason of this exception is one DataRow object cannot belong to more than one table. One solution, is to create a copy of this row with the help of the ImportRow method:
_DTCurrentAuspragung.ImportRow(RowAdd);
And don't forget to use Clone() after selecting rows, beacause both of these tables must have the same structure:
DataTable _DTCurrentAuspragung = _DTAuspragung.Clone();
So, the result is:
var DRCurrentAuspragung = _DTAuspragung.Select(#"MerkmalID = " + Convert.ToString(MerkmalID));
_DTCurrentAuspragung = _DTAuspragung.Clone();
for (int i = 0; i < DRCurrentAuspragung.Length; i++ )
{
DataRow RowAdd = DRCurrentAuspragung[i];
_DTCurrentAuspragung.ImportRow(RowAdd);
}
You may want to use the ImportRow() method. Remember that the table you're importing rows into has to have the same structure as the table the row you're importing belongs to (column names and types)
I have a datatable and a row. I want to import the row to the datatable only if it does not exist in the datatable.
How can i do that?
If you use a typed DataSet, I.e. declared in design time, the "linq Contains method" takes a typed DataRow. The default IEqualityComparer will compare all values in the DataRow. (Which is normally useless, since you should have a key defined).
DataSet1 ds = new DataSet1();
DataSet1.DataTable1Row row = ds.DataTable1.AddDataTable1Row(bla, bla);
bool exists = ds.DataTable1.Contains(row);
You can use LINQ to check if row is present in datatable. Follow this solution, and replace "id" with your row's primary key, by which you can uniquely identify a row in a table.
DataRow dr = null; // assign your DR here
DataTable dt = new DataTable(); // assign Datatable instance here.
var k = (from r in dt.Rows.OfType<DataRow>() where r["id"].ToString() == dr["id"].ToString() select r).FirstOrDefault();
if(k != null)
{ // Row is present }
if you want to check all the cells in a DataRow, you can try this function:
bool ContainDataRowInDataTable(DataTable T,DataRow R)
{
foreach (DataRow item in T.Rows)
{
if (Enumerable.SequenceEqual(item.ItemArray, R.ItemArray))
return true;
}
return false;
}
you can use Contains as below
if(DataTable.Columns.Contains("RowName"))
{
//Do some stuffs here
}
Tried all answers here but did not work, so I made something for myself which works in my case. The code is pretty simple, it checks if the row you want to add already exists in the datatable - if it does not exist in the datatable, add it.
// fill dt with information
DataTable dt = new DataTable();
// create a new row and fill it with information
DataRow dr = dt.NewRow();
// distinct
bool isDistinct = true;
for (int i=0; i < dt.Rows.Count; i++)
{
// check if both rows are equal
if (Enumerable.SequenceEqual(dt.Rows[i].ItemArray, dr.ItemArray))
{
// it already exists
isDistinct = false;
break;
}
}
if (isDistinct)
{
dt.Rows.Add(dr);
}
if ( Datatable1.Rows[NumOfRow].ToString().Deleted == "Deleted")
You should check row existence by comparing primary keys:
static bool RowExists(DataTable table, DataRow row)
{
var pk = table.PrimaryKey
.Select(column => row[column, DataRowVersion.Original])
.ToArray();
return table.Rows.Contains(pk);
}
Reason is, DataRow that you are trying to check against existing DataTable is, in real-life scenarios, different class instance compared to the DataRaw in the table, even when same DataRaw already exists in the DataTable. Usual .NET equality-comparison does not work properly in this scenarios. That includes DataTable.Contains(...) method.
To properly check for DataRaw existence in the table, primary key given DataRaw should be searched for in the table.
You can check using any with the key value
If (value.Tables(0).AsEnumerable().Any(Function(x) key = x.Field(Of Integer)("ProductId") ))
I have a problem with assigning string array into Datarow. Firstly, i have created the object for string array and put 2 values in the array out of 100(whole size). How many values should be placed in the array dependds on a different, which i am not showing here, though.
Then i tried converting into DataRow. But it says. "object reference not set to an instance of an object"
DataRow dr = null;
string[] strconcat = new string[100];
dr["concat"] = strconcat[i];
Thanks in advance
Edit-- Actually i was trying put these string array values into dropdown (ddchooseadeal). Is there any other good way other than this.
locname = ddchoosealoc.SelectedValue.ToString();
string[] strdeals = new string[100];
string[] strconcat = new string[100];
int i;
for(i =0; i< dsdeal.Tables[0].Rows.Count; i++)
{
strdeals[i] = Convert.ToString( dsdeal.Tables[0].Rows[i]["Title"]);
strconcat[i] = strdeals[i]+" -- "+ locname;
}
DataRow dr = null;
ddchooseadeal.Items.Clear();
ListItem li = new ListItem("Choose a Deal");
ddchooseadeal.Items.Add(li);
dr["drconcat"] = strconcat[0];
ListItem item = new ListItem();
item.Text = NullHandler.NullHandlerForString(strconcat[i], string.Empty);
ddchoosealoc.Items.Add(item);
Your DataRow is not a part of any DataTable which is actually right, that's why you can't instantiate a direct DataRow object.
So that's the theory part, to solve your problem
// Declare a DataTable object.
DataTable dt = new DataTable();
// Add some columns to the DataTable
dt.Columns.Add("StringHolder");
// Now suppose , you are having 10 items in your string array
foreach(string str in strArray)
{
DataRow drow = dt.NewRow() ; // Here you will get an actual instance of a DataRow
drow ["StringHolder"] = str; // Assign values
dt.Rows.Add(drow); // Don't forget to add the row to the DataTable.
}
So by following the above steps, you will have a DataTable populated with rows.
Your string array here has 100 elements, all null. So if you assign one of the elements into your data row, you are assigning null. Not a string.
If you are creating an array, the elements will remain uninitialised until you populate it with something. Value types will have their default value (0 for int, false for bool, etc.) while reference types (like string) default to null.
Also, dr is set to null in your example.
You are attempting to add values to a variable that is null DataRow dr = null; which is why you are getting the "object reference not set to an instance of an object" error.
You need to create a new datarow using your DataTable object, then adding the values to that DataRow. Without seeing more of the code it would be hard to offer much more help, but the following article from MSDN will get you started:
How to: Add Rows to a DataTable
check with your debugger if your desired column exists:
var x = dr["concat"];
and check if your desired value exists in the string array with:
var y = strconcat[i];
your datarow above is initialized with null so the error message is absolutely plausible.
you have to design a datatable with the columns you want. after that get a new row from that table and save the values from your string array to the datarow.
see msdn: how to add rows to a datatable => http://msdn.microsoft.com/en-us/library/5ycd1034%28VS.80%29.aspx
It throws NullPointerException because dr is null, you have to create dataRow with DataTable.NewRow Method
Building off Saurabh's answer, you can build a DataTable and it's columns and add each DataRow.
But there is a constructor for the DataRow that takes a params object[] values. So you can automatically add a whole string array to a DataRow, provided that the order of the elements matches the order of the columns specified:
// Create the data table
var dataTable = new DataTable("TableName");
// Add the columns you will need
dataTable.Columns.Add("FirstName");
dataTable.Columns.Add("LastName");
dataTable.Columns.Add("Whatever");
// Get your data in string array format
// Will need to be FirstName, LastName, Whatever
string[] data = LoadStringArrayFromCsvOrSomething();
// Add the DataRow using the string array
dataTable.Rows.Add(data);
This works great in conjunction with the Microsoft.VisualBasic.FileIO.TextFieldParser and the System.Data.SqlClient.SqlBulkCopy. You can throw data into SQL Server like its nobody's business.
How can I copy specific rows from DataTable to another Datable in c#? There will be more than one row.
foreach (DataRow dr in dataTable1.Rows) {
if (/* some condition */)
dataTable2.Rows.Add(dr.ItemArray);
}
The above example assumes that dataTable1 and dataTable2 have the same number, type and order of columns.
Copy Specified Rows from Table to another
// here dttablenew is a new Table and dttableOld is table Which having the data
dttableNew = dttableOld.Clone();
foreach (DataRow drtableOld in dttableOld.Rows)
{
if (/*put some Condition */)
{
dtTableNew.ImportRow(drtableOld);
}
}
Try This
String matchString="ID0001"//assuming we have to find rows having key=ID0001
DataTable dtTarget = new DataTable();
dtTarget = dtSource.Clone();
DataRow[] rowsToCopy;
rowsToCopy = dtSource.Select("key='" + matchString + "'");
foreach (DataRow temp in rowsToCopy)
{
dtTarget.ImportRow(temp);
}
Check this out, you may like it (previously, please, clone table1 to table2):
table1.AsEnumerable().Take(recodCount).CopyToDataTable(table2,LoadOption.OverwriteChanges);
Or:
table1.AsEnumerable().Where ( yourcondition ) .CopyToDataTable(table2,LoadOption.OverwriteChanges);
Supported in: 4, 3.5 SP1, you can now just call a method on the object.
DataTable dataTable2 = dataTable1.Copy()
As a result of the other posts, this is the shortest I could get:
DataTable destTable = sourceTable.Clone();
sourceTable.AsEnumerable().Where(row => /* condition */ ).ToList().ForEach(row => destTable.ImportRow(row));
I've created an easy way to do this issue
DataTable newTable = oldtable.Clone();
for (int i = 0; i < oldtable.Rows.Count; i++)
{
DataRow drNew = newTable.NewRow();
drNew.ItemArray = oldtable.Rows[i].ItemArray;
newTable.Rows.Add(drNew);
}
I needed to copy rows from multiple tables with the same structure into a new table to be used as a datasource for datagridview:
// Generate DataTable[] alltables from multiple datatables
DataTable newTable = alltables[0].Clone();
foreach (DataTable dt in alltables)
{
for (int i = 0; i < dt.Rows.Count; i++)
newTable.Rows.Add(dt.Rows[i].ItemArray);
}
below sample would be the fastest way to copy one row.
each cell is being copied based on the column name.
in case you dont need a specific cell to copy then have a try catch or add if.
if your going to copy more than 1 row then loop the code below.
DataRow dr = dataset1.Tables[0].NewRow();
for (int i = 0; i < dataset1.Tables[1].Columns.Count; i++)
{
dr[dataset1.Tables[1].Columns[i].ColumnName] = dataset1.Tables[1].Rows[0][i];
}
datasetReport.Tables[0].Rows.Add(dr);
dataset1.Tables[1].Rows[0][i]; change the index 0 to your specified row index or you can use a variable if your going to loop or if its going to be logical
private void CopyDataTable(DataTable table){
// Create an object variable for the copy.
DataTable copyDataTable;
copyDataTable = table.Copy();
// Insert code to work with the copy.
}
To copy whole datatable just do this:
DataGridView sourceGrid = this.dataGridView1;
DataGridView targetGrid = this.dataGridView2;
targetGrid.DataSource = sourceGrid.DataSource;
For those who want single command SQL query for that:
INSERT INTO TABLE002
(COL001_MEM_ID, COL002_MEM_NAME, COL002_MEM_ADD, COL002_CREATE_USER_C, COL002_CREATE_S)
SELECT COL001_MEM_ID, COL001_MEM_NAME, COL001_MEM_ADD, COL001_CREATE_USER_C, COL001_CREATE_S
FROM TABLE001;
This query will copy data from TABLE001 to TABLE002 and we assume that both columns had different column names.
Column names are mapped one-to-one like:
COL001_MEM_ID -> COL001_MEM_ID
COL001_MEM_NAME -> COL002_MEM_NAME
COL001_MEM_ADD -> COL002_MEM_ADD
COL001_CREATE_USER_C -> COL002_CREATE_USER_C
COL002_CREATE_S -> COL002_CREATE_S
You can also specify where clause, if you need some condition.
There is better way to do this.
DataTable targetDataTable = new DataTable();
targetDataTable = changedColumnMetadata.AsEnumerable().Where(dataRow => entityName.Equals(dataRow["EntityName"])).CopyToDataTable();
Please try this and let me know in case of any issues.
You can do it calling the DataTable.Copy() method, for example:
DataSet ds = new DataSet();
System.Data.DataTable dt = new System.Data.DataTable();
dt = _BOSearchView.DS.Tables[BusLib.TPV.TableName.SearchView].Copy();
ds.Tables.Add(dt);
UltGrdSaleExcel.SetDataBinding(ds, dt.TableName, true);
use Merge, this will append all rows of newDataTable with oldDateTale
oldDateTale.Merge(newDataTable);