Simple way to convert datarow array to datatable - c#

I want to convert a DataRow array into DataTable ... What is the simplest way to do this?

For .Net Framework 3.5+
DataTable dt = new DataTable();
DataRow[] dr = dt.Select("Your string");
DataTable dt1 = dr.CopyToDataTable();
But if there is no rows in the array, it can cause the errors such as The source contains no DataRows. Therefore, if you decide to use this method CopyToDataTable(), you should check the array to know it has datarows or not.
if (dr.Length > 0)
DataTable dt1 = dr.CopyToDataTable();
Reference available at MSDN:
DataTableExtensions.CopyToDataTable Method (IEnumerable)

Why not iterate through your DataRow array and add (using DataRow.ImportRow, if necessary, to get a copy of the DataRow), something like:
foreach (DataRow row in rowArray) {
dataTable.ImportRow(row);
}
Make sure your dataTable has the same schema as the DataRows in your DataRow array.

DataTable dt = new DataTable();
DataRow[] dr = (DataTable)dsData.Tables[0].Select("Some Criteria");
dt.Rows.Add(dr);

Another way is to use a DataView
// Create a DataTable
DataTable table = new DataTable()
...
// Filter and Sort expressions
string expression = "[Birth Year] >= 1983";
string sortOrder = "[Birth Year] ASC";
// Create a DataView using the table as its source and the filter and sort expressions
DataView dv = new DataView(table, expression, sortOrder, DataViewRowState.CurrentRows);
// Convert the DataView to a DataTable
DataTable new_table = dv.ToTable("NewTableName");

Simple way is:
// dtData is DataTable that contain data
DataTable dt = dtData.Select("Condition=1").CopyToDataTable();
// or existing typed DataTable dt
dt.Merge(dtData.Select("Condition=1").CopyToDataTable());

DataTable Assetdaterow =
(
from s in dtResourceTable.AsEnumerable()
where s.Field<DateTime>("Date") == Convert.ToDateTime(AssetDate)
select s
).CopyToDataTable();

DataTable dt = myDataRowCollection.CopyToDataTable<DataRow>();

DataTable dt = new DataTable();
foreach (DataRow dr in drResults)
{
dt.ImportRow(dr);
}

.Net 3.5+ added DataTableExtensions, use DataTableExtensions.CopyToDataTable Method
For datarow array just use .CopyToDataTable() and it will return datatable.
For single datarow use
new DataRow[] { myDataRow }.CopyToDataTable()

You could use System.Linq like this:
if (dataRows != null && dataRows.Length > 0)
{
dataTable = dataRows.AsEnumerable().CopyToDataTable();
}

Here is the solution. It should work fine.
DataTable dt = new DataTable();
dt = dsData.Tables[0].Clone();
DataRows[] drResults = dsData.Tables[0].Select("ColName = 'criteria');
foreach(DataRow dr in drResults)
{
object[] row = dr.ItemArray;
dt.Rows.Add(row);
}

Incase anyone needs it in VB.NET:
Dim dataRow as DataRow
Dim yourNewDataTable as new datatable
For Each dataRow In yourArray
yourNewDataTable.ImportRow(dataRow)
Next

You need to clone the structure of Data table first then import rows using for loop
DataTable dataTable =dtExisting.Clone();
foreach (DataRow row in rowArray) {
dataTable.ImportRow(row);
}

DataTable dataTable = new DataTable();
dataTable = OldDataTable.Tables[0].Clone();
foreach(DataRow dr in RowData.Tables[0].Rows)
{
DataRow AddNewRow = dataTable.AddNewRow();
AddNewRow.ItemArray = dr.ItemArray;
dataTable.Rows.Add(AddNewRow);
}

Related

c# split one datatable to several into dataset

I have correct source DataTable "sourceDataTable" and I call method to split it into several and store the result into DataSet "ds":
DataSet ds = MyClass.SplitDataTables(sourceDataTable);
Here is the method MyClass.SplitDataTables():
public static DataSet SplitDataTables(DataTable sourceDataTable)
{
using (DataSet dsOut = new DataSet())
{
DataTable dt1 = new DataTable;
DataTable dt2 = new DataTable;
DataTable dt3 = new DataTable;
dt1 = sourceDataTable.Clone();
dt2 = sourceDataTable.Clone();
dt3 = sourceDataTable.Clone();
foreach (DataRow row in sourceDataTable.Rows)
{
//column is for example "City" and some row has "Boston" in it, so I put this row into dt1
if (row["ColumnName"].ToString() == "something")
{
dt1.ImportRow(row);
}
else if (...)
{ } //for other DataTables dt2, dt3, etc...
else .......... ;
}
//here I put resulting DataTables into one DataSet which is returned
string[] cols= { "dt1", "dt2", "dt3" };
foreach (string col in cols)
{
dsOut.Tables.Add(col);
}
return dsOut;
}
}
So with this returned DataSet I display new Windows each with one DataTable
foreach (DataTable dtt in ds.Tables)
{
string msg = dtt.TableName;
Window2 win2 = new Window2(dtt, msg);
win2.Show();
}
All I get shown is Windows with placeholder for "empty DataGrid"
Windows code is correct, as it works whith "unsplit DataTable".
I assume code in splitting DataTables is all wrong as it does not output DataSet with filled DataTables. I will greatly appreciate any help on this issue. Thank you!
You don't need a for loop here
Replace below code
string[] cols= { "dt1", "dt2", "dt3" };
foreach (string col in cols)
{
dsOut.Tables.Add(col);
}
With this
dsOut.Tables.Add(dt1);
dsOut.Tables.Add(dt2);
dsOut.Tables.Add(dt3);
Thanks to #Krishna I got this solved. So if you ever encounter similar problem here are 2 things to note:
string[] cols = { "dt1", "dt2", "dt3", ... };
foreach (string col in cols)
{
dsOut.Tables.Add(col);
}
This cycle does not have access to objects of DataTables with same name and writes only empty DataTables into DataSet collection (regardless of same name!).
If you create new DataTable and you will be making it a clone of another DataTable, dont bother yet with setting its name.
DataTable dt1 = new DataTable();
Make new DataTable of same format as source DataTable:
dt1 = sourceDataTable.Clone();
dt2 = sourceDataTable.Clone();
//etc...
Now you have to set unique DataTable names to each DataTable cloned from source DataTable:
dt1.TableName = "Name1";
dt2.TableName = "Name2";
//and so on
Now all works as intended.

filter a data table with values from an array c#

I have a delete method, it gets an array of GUIDs and I have a data table... how can I filter the data table so it will only contain thoes GUIDs?
public void delete(Guid[] guidlist)
{
datatable template = ReadTemplateList()
...
}
Thank you!
With Linq to DataSet you can create new DataTable which will have only rows with those Guids:
public void Delete(Guid[] guids)
{
DataTable table = ReadTemplateList()
.AsEnumerable()
.Where(r => guids.Contains(r.Field<Guid>("ColumnName")))
.CopyToDataTable();
// ...
}
Another option (which also will work on old .NET versions) is filtering your table with built-in RowFilter functionality which supports IN filters. Let's assume you are filtering by column named ID:
// Check if guids.Length > 0
StringBuilder filter = new StringBuilder("ID IN (");
foreach (Guid id in guids)
filter.AppendFormat("Convert('{0}','System.Guid'),", id);
filter.Append(")");
DataTable template = ReadTemplateList();
DataView view = template.DefaultView;
view.RowFilter = filter.ToString();
DataTable table = view.ToTable();
You can use LINQ:
public static DataTable DeleteGuidsFromTemplate(Guid[] guidlist)
{
DataTable template = ReadTemplateList();
var rowsWithGuids = from row in template.AsEnumerable()
join guid in guidlist
on row.Field<Guid>("Guid") equals guid
select row;
return rowsWithGuids.CopyToDataTable();
}
If you can't use LINQ since you're lower than NET 3.5:
public static DataTable DeleteGuidsFromTemplate(Guid[] guidlist)
{
DataTable template = ReadTemplateList();
DataTable templateGuids = template.Clone();
foreach(DataRow row in template.Rows)
{
Guid guid = (Guid)row["Guid"];
int index = Array.IndexOf(guidlist, guid);
if (index >= 0)
templateGuids.ImportRow(row);
}
return templateGuids;
}
A solution based on DataTable and DataRows.
//fill the datatable from back end
string connStr = ConfigurationManager.ConnectionStrings["ConsoleApplication1.Properties.Settings.NORTHWNDConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(connStr);
conn.Open();
SqlCommand comm = new SqlCommand("select categoryid,categoryname from Categories order by categoryname");
comm.Connection = conn;
SqlDataReader dr = comm.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(dr);
//datatable filter logic
string[] filter = { "1", "2" };
DataTable filteredTable = dt.Clone();
foreach (string str in filter)
{
DataRow[] filteredRows = dt.Select("categoryid="+ str); //search for categoryID
foreach (DataRow dtr in filteredRows)
{
filteredTable.ImportRow(dtr);
}
}
EDIT
Without going in the for loop
DataTable dt = new DataTable();
dt.Load(dr); //fill the datatable with sqldatareader
DataTable filteredTable = dt.Clone();
DataView dv = dt.DefaultView;
dv.RowFilter = "categoryid in (1,2)";
filteredTable = dv.ToTable();

dataview rowfilter value to datatable convertion

I want to convert dataview rowfilter value to datatable. I have a dataset with value. Now i was filter the value using dataview. Now i want to convert dataview filter values to datatable.please help me to copy it........
My partial code is here:
DataSet5TableAdapters.sp_getallempleaveTableAdapter TA = new DataSet5TableAdapters.sp_getallempleaveTableAdapter();
DataSet5.sp_getallempleaveDataTable DS = TA.GetData();
if (DS.Rows.Count > 0)
{
DataView datavw = new DataView();
datavw = DS.DefaultView;
datavw.RowFilter = "fldempid='" + txtempid.Text + "' and fldempname='" + txtempname.Text + "'";
if (datavw.Count > 0)
{
DT = datavw.Table; // i want to copy dataview row filter value to datatable
}
}
please help me...
You can use
if (datavw.Count > 0)
{
DT = datavw.ToTable(); // This will copy dataview's RowFilterd values to datatable
}
You can use DateView.ToTable() for converting the filtered dataview in to a datatable.
DataTable DTb = new DataTable();
DTb = SortView.ToTable();
The answer does not work for my situation because I have columns with expressions. DataView.ToTable() will only copy the values, not the expressions.
First I tried this:
//clone the source table
DataTable filtered = dt.Clone();
//fill the clone with the filtered rows
foreach (DataRowView drv in dt.DefaultView)
{
filtered.Rows.Add(drv.Row.ItemArray);
}
dt = filtered;
but that solution was very slow, even for just 1000 rows.
The solution that worked for me is:
//create a DataTable from the filtered DataView
DataTable filtered = dt.DefaultView.ToTable();
//loop through the columns of the source table and copy the expression to the new table
foreach (DataColumn dc in dt.Columns)
{
if (dc.Expression != "")
{
filtered.Columns[dc.ColumnName].Expression = dc.Expression;
}
}
dt = filtered;
The below code is for Row filter from Dataview and the result converted in DataTable
itemCondView.RowFilter = "DeliveryNumber = '1001'";
dataSet = new DataSet();
dataSet.Tables.Add(itemCondView.ToTable());

how to add datatable to dataset in asp.net

DataSet ds = new DataSet();
DataRow[] foundRows;
foundRows = ds.Tables[0].Select("MerchantName LIKE '%'", "MerchantName");
DataTable DataTable2 = new DataTable();
DataTable2 = ds.Tables[0].Clone();
foreach (DataRow dr in foundRows)
{
DataTable2.ImportRow(dr);
}
ds.tables[0].rows.add(DataTable2); // error table already exists.
Loadimages(ds);
hi all,
upto foreach loop everything is working fine. In loadimages method i have to dataset. but i have the data in datatable. If i add datatable to dataset i am getting the error saying table already exists.
Please help me regarding this.
Thanks in advance..
I don't understand why you're trying to add a DataTable into another DataTable. Surely your code should be as follows:
DataSet ds = new DataSet();
DataRow[] foundRows;
foundRows = ds.Tables[0].Select("MerchantName LIKE '%'", "MerchantName");
DataTable DataTable2 = new DataTable();
DataTable2 = ds.Tables[0].Clone();
DataTable2.TableName = "DataTable2";
foreach (DataRow dr in foundRows)
{
DataTable2.ImportRow(dr);
}
ds.Tables.Add(DataTable2);
Loadimages(ds);
The reason for your error is because your DataTables within the DataSet must have unique names.

How to get columns from a datarow?

I have a row collection (DataRow[] rows). And I want to import all rows to another DataTable (DataTable dt).
But how?
Code
DataTable dt;
if (drs.Length>0)
{
dt = new DataTable();
foreach (DataRow row in drs)
{
dt.Columns.Add(row???????)
}
// If it possible, something like that => dt.Columns.AddRange(????????)
for(int i = 0; i < drs.Length; i++)
{
dt.ImportRow(drs[i]);
}
}
Assuming the rows all have the same structure, the easiest option is to clone the old table, omitting the data:
DataTable dt = drs[0].Table.Clone();
Alternatively, something like:
foreach(DataColumn col in drs[0].Table.Columns)
{
dt.Columns.Add(col.ColumnName, col.DataType, col.Expression);
}
If your DataRows is from a Data Table with Columns defined in it,
DataRow[] rows;
DataTable table = new DataTable();
var columns = rows[0].Table.Columns;
table.Columns.AddRange(columns.Cast<DataColumn>().ToArray());
foreach (var row in rows)
{
table.Rows.Add(row.ItemArray);
}
How about
DataTable dt = new DataTable;
foreach(DataRow dr in drs)
{
dt.ImportRow(dr);
}
Note this only works if drs is a DataRowCollection. Detached rows (not in a DataRowCollection are ignored).
Don't forget to call AcceptChanges.
Try this:
// Assuming you have a DataRow object named row:
foreach(DataColumn col in row.Table.Columns)
{
// Do whatever you need to with these columns
}

Categories