how to copy a row of a dataset into another dataset? [duplicate] - c#

This question already has answers here:
Copy rows from one Datatable to another DataTable?
(15 answers)
Closed 7 years ago.
i am looping through a dataset with 2 loops trying to find the rows which have have their ID matched with the assigned value to an array and if they matched i would like to copy that row into another table. for example:
DataSet dsWinners = new DataSet();
for(int i =0;i<=TotalWinners;i++)
{
for (int j = 1; j <= ds.Tables[0].Rows.Count; j++)
{
//this is my ds table 0
left = Convert.ToInt16(ds.Tables[0].Rows[i]["ID"]);
//this is my array
right = Convert.ToInt16(Winners[i, 0]);
if ( left == right )//if array value matechs with ds.table[0] ID
{
dsWinners.Tables[0].Rows[i] = ds.Tables[0].Rows[j];
}
}
}
how can i get record/row And copy it into a new table and if i cant copy that row like this, is there an alternative way to do it?

DataTable tempDt = new DataTable();
tempDt = ds.Tables[0].Clone();
ds.Tables[0].Rows.OfType<DataRow>().ToList().ForEach(x =>
{
int rowIndex = ds.Tables[0].Rows.IndexOf(x);
if (rowIndex < TotalWinners &&
Convert.ToInt16(x["ID"]) == Convert.ToInt16(Winners[rowIndex, 0]))
{
tempDt.ImportRow(x);
}
});
DataSet dsWinners = new DataSet();
dsWinners.Tables.Add(tempDt);
EDIT:
Dictionary<string, string> winnersList = new Dictionary<string, string>();
for (int i = 0; i < TotalWinners; i++)
{
winnersList.Add(Winners[i, 0], Winners[i, 1]);
}
string idList = string.Join("','", winnersList.Select(x => x.Key));
DataSet dsWinners = new DataSet();
dsWinners.Tables.Add(ds.Tables[0].Select("ID IN ('" + idList + "')").CopyToDataTable());
dsWinners.Tables[0].Columns.Add("prize_amt", typeof(string));
dsWinners.Tables[0].Rows.OfType<DataRow>().ToList().ForEach(x =>
{
x["prize_amt"] = winnersList[x["ID"].ToString()];
});
dsWinners.Tables[0].AcceptChanges();
Hope this helps...

DataSet dsWinners = new DataSet();
DataTable dataTable= ds.Tables[0].Clone();
for(int i =0;i<=TotalWinners;i++)
{
for (int j = 1; j <= ds.Tables[0].Rows.Count; j++)
{
//this is my ds table 0
left = Convert.ToInt16(ds.Tables[0].Rows[i]["ID"]);
//this is my array
right = Convert.ToInt16(Winners[i, 0]);
if ( left == right )//if array value matechs with ds.table[0] ID
{
// dsWinners.Tables[0].Rows[i] = ds.Tables[0].Rows[j];
dataTable.Rows.Add( ds.Tables[0].Rows[j]);
}
}
}
dsWinners.Add(dataTable);

DataSet ds = new DataSet();
DataTable dt = new DataTable("ExampleTable");
dt.Columns.Add(new DataColumn("Age",typeof(int)));
dt.Columns.Add(new DataColumn("Name", typeof(string)));
DataRow dr = dt.NewRow();
dr["Age"] = 30;
dr["Name"] = "Mike";
dt.Rows.Add(dr);
ds.Tables.Add(dt);

If i read your question right then you need to copy rows from one dataset when certain condition is met and transfer it to other one.Assuming that both the dataset have same structure this example should suffice.
DataSet DSResult = new DataSet();
DSResult.Tables.Add();
DSResult.Tables[0].Columns.Add("ID", typeof(int));
DSResult.Tables[0].Columns.Add("Name", typeof(string));
DSResult.Tables[0].Rows.Add(1,"Jon");
DSResult.Tables[0].Rows.Add(2, "Kyle");
DSResult.Tables[0].Rows.Add(3, "Sam");
DSResult.Tables[0].Rows.Add(4, "Peter");
DSResult.Tables[0].Rows.Add(5, "Lily");
DataSet DSWinners = new DataSet();
DSWinners.Tables.Add();
DSWinners = DSResult.Clone();
int[] Id = new int[] { 1, 4, 5 }; //condition to match
foreach (int val in Id)
{
DataRow[] Samplerow =
DSResult.Tables[0].AsEnumerable()
.Select((row, index) => new { row, index })
.Where(item => item.row.Field<int>("ID") == val)
.Select(item => item.row)
.ToArray();
DSWinners.Tables[0].ImportRow(Samplerow[0]);
// If both tables are not same then
string YourVal=Samplerow[0]["ID"].ToString();
DSWinners.Tables[0].Rows.Add();
DSWinners.Tables[0].Rows[0]["YourColumnname"]=Yourval //Should have same Datataype
}

Related

Row already belongs to another table error when trying to add rows?

I tried this solution below:
This Row already belongs to another table error when trying to add rows?
I have a Datatable that contains 597 Columns and 20 Rows and are trying to export the data to excel. However, Excel has a maximum column count 256 and so I need to divide the source data into 3 datatables to make the export work.
Below is the code I have written.
var dtmasterdata = data.Tables[name];
for (int j = 1; j < datatableNumberCount; j++)
{
DataTable dt2 = new DataTable();
dt2.TableName = "Master_" + j;
dt2 = dtmasterdata.Copy();
foreach (DataColumn col in dtmasterdata.Columns)
{
DataColumn dtcol = new DataColumn();
dtcol = col;
dt2.Columns.Add(dtcol.ColumnName, dtcol.DataType);
}
for (int k = 0; k < dtmasterdata.Rows.Count; k++)
{
DataRow dr = dt2.NewRow();
dr = dtmasterdata.Rows[k];
dt2.ImportRow(dtmasterdata.Rows[k]);
//dt2.Rows.Add(dr.ItemArray);
}
After that I need to delete few columns like below and I want to create 3 datatables
foreach (DataColumn col in dtmasterdata.Columns)
{
if (j == 1)
{
// condition 1
if (col.Ordinal >= 255)
{
dt2.Columns.RemoveAt(col.Ordinal);
}
}
if (j == 2)
{
// condition 2.
if (col.Ordinal < 255 || col.Ordinal >= 510)
{
dt2.Columns.RemoveAt(col.Ordinal);
}
}
if (j == 3)
{
// condition 3.
if (col.Ordinal <= 510 || col.Ordinal >= 765)
{
dt2.Columns.Add(col);
}
}
}
int worksheetNumber = 1;
string worksheetNameWithNumber = "Master Data";
if (worksheetNumber > 1)
worksheetNameWithNumber = String.Format("{0}_{1}", ws1, worksheetNumber.ToString());
Infragistics.Excel.Worksheet worksheet = wb.Worksheets.Add(worksheetNameWithNumber);
Infragistics.WebUI.UltraWebGrid.UltraWebGrid masterData1 = new Infragistics.WebUI.UltraWebGrid.UltraWebGrid("masterDataGrid");
masterData1.Browser = Infragistics.WebUI.UltraWebGrid.BrowserLevel.UpLevel;
masterData1.DataSource = dt2;
masterData1.DataMember = "Master_" + j;
masterData1.DisplayLayout.HeaderStyleDefault.Font.Bold = true;
masterData1.DisplayLayout.HeaderStyleDefault.Font.Name = "Arial";
masterData1.DisplayLayout.HeaderStyleDefault.Font.Size = FontUnit.Parse("10px");
masterData1.DisplayLayout.HeaderStyleDefault.BackColor = System.Drawing.Color.LightGray;
masterData1.DisplayLayout.RowStyleDefault.Font.Name = "Arial";
masterData1.DisplayLayout.RowStyleDefault.Font.Size = FontUnit.Parse("10px");
Infragistics.WebUI.UltraWebGrid.UltraGridBand masterBand1 = new Infragistics.WebUI.UltraWebGrid.UltraGridBand();
masterData1.Bands.Add(masterBand1);
dgResults.Controls.Add(masterData1);
masterData1.DataBind();
wb.ActiveWorksheet = worksheet;
this.ugWebGridExporter.Export(masterData1, worksheet);
worksheetNumber++;
Your error is because you are trying to add a column to a datatable that already belongs to your source datatable.
dt2.Columns.Add(col);
You can't just iterate through the columns of a datatable and add them to another.
I've a solution to this, which involves cloning the source data and removing what you don't need.
1st, make 3 clones of the datatables you need. Below is an example with me creating my own source table with 596 columns. Notice that clone only takes the data table structure, no data!
var source597ColsTable = new DataTable("Source");
for (var i = 0; i <= 596; i++)
{
source597ColsTable.Columns.Add(new DataColumn("Column" + i , typeof(string)));
}
DataRow newRow = source597ColsTable.NewRow();
source597ColsTable.Rows.Add(newRow);
var cols0To199Table = source597ColsTable.Clone();
var cols200To399Table = source597ColsTable.Clone();
var cols400To596Table = source597ColsTable.Clone();
Next copy all the rows from the source table into the clones. The below is a simple function to do so.
private DataTable CopyRowsFromSource(DataTable sourceTable, DataTable destinationTable)
{
foreach (DataRow row in sourceTable.Rows)
{
destinationTable.Rows.Add(row.ItemArray);
}
return destinationTable;
}
Then call this function for each of your tables.
cols0To199Table = CopyRowsFromSource(source597ColsTable, cols0To199Table);
cols200To399Table = CopyRowsFromSource(source597ColsTable, cols200To399Table);
cols400To596Table = CopyRowsFromSource(source597ColsTable, cols400To596Table);
Finally, remove all the columns from the datatables to give you your split.
private DataTable RemoveColumns(DataTable table, int startCol, int endCol)
{
var colsToRemove = new List<DataColumn>();
for (var colCount = startCol; colCount <= endCol; colCount++)
{
colsToRemove.Add(table.Columns[colCount]);
}
foreach (DataColumn col in colsToRemove)
{
table.Columns.Remove(col);
}
return table;
}
Then call.. again for each cloned table.
cols0To199Table = RemoveColumns(cols0To199Table, 200, 596);
cols200To399Table = RemoveColumns(cols200To399Table, 0, 199);
cols200To399Table = RemoveColumns(cols200To399Table, 200, 396);
cols400To596Table = RemoveColumns(cols400To596Table, 0, 399);
After running this, you will have 3 datatables, columns 0-199, 200-399 and 400-596.
Hope that helps.
I am not sure to have really understood all of your code, but to copy a subset of columns to another datatable there is a very simple method in the DataView class named ToTable where you can list the columns you want in the new table. As added bonus, this method copies also the data in the 20 rows of your original table.
So the only difficult is to list these columns to the method.
You can proceed in this way using linq over the DataColumn collection
string[] firstCols = dtmasterdata.Columns
.Cast<DataColumn>()
.Take(255)
.Select(x => x.ColumnName).ToArray();
string[] secondCols = dtmasterdata.Columns
.Cast<DataColumn>()
.Skip(255)
.Take(255)
.Select(x => x.ColumnName).ToArray();
string[] thirdCols = dtmasterdata.Columns
.Cast<DataColumn>()
.Skip(510)
.Select(x => x.ColumnName).ToArray();
DataTable t1 = dtmasterdata.DefaultView.ToTable("Master_1", false, firstCols);
DataTable t2 = dtmasterdata.DefaultView.ToTable("Master_2", false, secondCols);
DataTable t3 = dtmasterdata.DefaultView.ToTable("Master_3", false, thirdCols);

A data item was not found in the container. The container must either implement IDataItemContainer, or have a property named DataItem

I am trying to bind string array to grid view. While using the given below code showing the error "A data item was not found in the container. The container must either implement IDataItemContainer, or have a property named DataItem." Please help me to find a proper solution. Thank you.
Code:
protected void ddlCircle_SelectedIndexChanged(object sender, EventArgs e)
{
ShadingAnalysisDataSetTableAdapters.tbl_CadEngineersTeamTableAdapter cd;
cd = new ShadingAnalysisDataSetTableAdapters.tbl_CadEngineersTeamTableAdapter();
DataTable dt = new DataTable();
dt = cd.GetAvailableData(ddlCircle.SelectedValue); // Getting details of unassigned site
int x, y; //z;
DataTable dt3 = new DataTable();
dt3 = cd.GetTeam();
y = dt3.Rows.Count;
x = dt.Rows.Count; // counting the unassinged sites
DataTable dt2 = new DataTable();
dt2 = cd.GetAssignTeam(x); //Getting team based on count
string[] arr = new string[dt2.Rows.Count];
int i = 0;
foreach (DataRow r in dt2.Rows)
{
arr[i] = r["Team"].ToString(); // assigning available team to array
i++;
}
string[] strArr = new string[100]; // another array to copy arr values.
i = 0; int j = 0;
while (j <= x)
{
strArr[j]= arr[i] ; // copying the arr[] values into strArr[] based on count.
i++;
j++;
if (i == 3)
{
i = 0;
}
}
GridView2.DataSource = strArr;
GridView2.DataBind(); // error popup here
}
Define a GridView's column such that it binds to the Team column of your DataTable and assign the DataTable directly to the GridView as DataSource. Then DataBind to the DataTable.
Binding Array to DataGrid is just like putting bananas in egg tray. Please you have to bind a source having structure according to datagrid. As suggested by #Konstantin D - Infragistics
Now the gridview showing strArr[j] array values
protected void ddlCircle_SelectedIndexChanged(object sender, EventArgs e)
{
ShadingAnalysisDataSetTableAdapters.tbl_CadEngineersTeamTableAdapter cd;
cd = new ShadingAnalysisDataSetTableAdapters.tbl_CadEngineersTeamTableAdapter();
DataTable dt = new DataTable();
dt = cd.GetAvailableData(ddlCircle.SelectedValue); // Getting details of unassigned site
int x, y; //z;
DataTable dt3 = new DataTable();
dt3 = cd.GetTeam();
y = dt3.Rows.Count;
x = dt.Rows.Count; // counting the unassinged sites
DataTable dt2 = new DataTable();
dt2 = cd.GetAssignTeam(x); //Getting team based on count
string[] arr = new string[dt2.Rows.Count];
int i = 0;
foreach (DataRow r in dt2.Rows)
{
arr[i] = r["Team"].ToString(); // assigning available team to array
i++;
}
string[] strArr = new string[x+1]; // another array to copy arr values.
i = 0; int j = 0;
while (j <= x)
{
strArr[j]= arr[i] ; // copying the arr[] values into strArr[] based on count.
i++;
j++;
if (i == 3)
{
i = 0;
}
}
GridView2.DataSource = strArr;
GridView2.DataBind();
}

list Values to dataTable

I created a list from an excel document that has partnumbers on the every other starting with the first, and prices on every other row, starting with the second.
Lets say I initialize a datatable like so..
DataTable priceListTable = new DataTable();
priceListTable.Columns.Add("ItemNumber", typeof(string));
priceListTable.Columns.Add("Price", typeof(Float));
And my list (called recordList) looks this;
001-001
1.45
001-002
3.49
How do I get the first two rows of the list to fill the columns of the dataTable?
Here's one solution.
Loop over the list 2 items at a time starting from the 2nd item. This makes sure you always have a pair of items to use.
for (int i = 1; i < list.Count; i += 2)
{
DataRow row = table.NewRow();
row["ItemNumber"] = list[i-1];
row["Price"] = list[i];
table.Rows.Add(row);
}
string ItemNumber = "ItemNumber";
string Price = "Price";
DataTable priceListTable = new DataTable();
DataRow row;
priceListTable.Columns.Add(ItemNumber);
priceListTable.Columns.Add(Price);
int counter = 0;
foreach(string s in recordList)
{
myTableSize++;
}
foreach(string s in recordList)
{
if (counter < myTableSize)
{
row = priceListTable.NewRow();
row[ItemNumber] = recordList[counter];
row[Price] = recordList[counter + 1];
priceListTable.Rows.Add(row);
counter++;
counter++;
}

How to iterate through DataTable cells

I need to get the count of all cells in a DataTable, how can i do this ? I need this to verify that my 2 tables has the same cell amount before inserting data into a database.
Try this:
DataTable dt1 = new DataTable(), dt2 = new DataTable();
// define and populate your tables
int count1 = dt1.Columns.Count * dt1.Rows.Count;
int count2 = dt2.Columns.Count * dt2.Rows.Count;
bool verified = count1 == count2;
DataTable tbl = new DataTable();
foreach (DataRow row in tbl.Rows)
{
foreach (DataColumn col in tbl.Columns)
{
object cellData = row[col];
}
}

how to compare 2 datatable and get unique records in 3rd datatable?

I have 2 datatable let say dtData1 and dtData2. I have records in both the datatable I want to compare both the data table and want to create a new datatable let say dtData3 with uniqe records.
suppose: dtData1 has 10 records, and dtData2 has 50 records, but what ever records are there in dtData2 in that 7 records are same as dtData1. So here I want unique records in dtData3, means I want only 43 records in dtData3.
we don't know in datatable where we have the duplicate, and its possible that we will not have duplicates or its also possible that we will have all duplicate records.
So in dtData3 I need unique records
Some one please help me.
var dtData3 = dtData2.AsEnumerable().Except(dtData1.AsEnumerable(), DataRowComparer.Default);
Use this.. Probably it will help you.
Suppose you have two data table
DataTable dt1 = new DataTable();
dt1.Columns.Add("Name");
dt1.Columns.Add("ADD");
DataRow drow;
for (int i = 0; i < 10; i++)
{
drow = dt1.NewRow();
drow[0] = "NameA" + 1;
drow[1] = "Add" + 1;
dt1.Rows.Add();
}
DataTable dt2 = new DataTable();
dt2.Columns.Add("Name");
dt2.Columns.Add("ADD");
DataRow drow1;
for (int i = 0; i < 11; i++)
{
drow1 = dt2.NewRow();
drow1[0] = "Name" + 1;
drow1[1] = "Add" + 1;
dt2.Rows.Add();
}
Now To solve your problem Call :-
DataTable d3 = CompareTwoDataTable(dt1, dt2);
The method is something like this;--
public static DataTable CompareTwoDataTable(DataTable dt1, DataTable dt2)
{
dt1.Merge(dt2);
DataTable d3 = dt2.GetChanges();
return d3;
}
Then where the need to compare dtData1 and dtData2? Instead you can copy the contents from dtData2 to dtData3 starting from index7.
First Create Array variables to save unique coloumn values for datatable3. Use Foreach loop with second gridview rows. If any match then dnt save it in a array value, if dnt match then save it in arrays. and display it by attaching with third gridview.......
e.g
string[] name = new string[4];
int i=0,j=0;
foreach(GridViewRows gv in GridView1.rows)
{
if(gv.Cells[0].Text == GridView2.Rows[i].Cells[0].Text)' //if match
{
// dnt save
}
else' //if dnt match save in array for further use
{
name[j] = gv.Cells[0].Text;
j= j++;
}
i=i++;
}
After Saving unique values in Array "name"...Bind it in Third Gridview
During DataBound of third Gridview add this method...
Private void GridView3_RowDataBound(object sender,EventArgs e)
{
if(e.Row.RowState == DataControlState.DataRow)
{
foreach(string nm in name)
{
e.Rows.Cells.Add(name);
}
}
}
public DataTable CompareTwoDataTable(DataTable dtOriginalTable, DataTable dtNewTable, ArrayList columnNames)
{
DataTable filterTable = new DataTable();
filterTable = dtNewTable.Copy();
string filterCriterial;
if (columnNames.Count > 0)
{
for (int iNewTableRowCount = 0; iNewTableRowCount < dtNewTable.Rows.Count; iNewTableRowCount++)
{
filterCriterial = string.Empty;
foreach (string colName in columnNames.ToArray())
{
filterCriterial += colName.ToString() + "='" + dtNewTable.Rows[iNewTableRowCount][colName].ToString() + "' AND ";
}
filterCriterial = filterCriterial.TrimEnd((" AND ").ToCharArray());
DataRow[] dr = dtOriginalTable.Select(filterCriterial);
if (dr.Length > 0)
{
filterTable.Rows[filterTable.Rows.IndexOf(filterTable.Select(filterCriterial)[0])].Delete();
}
}
}
return filterTable;
}

Categories