ADO.NET: convert a DataTable to an array of DataRows - c#

I'm using ADO.NET and C#, and I want to convert a DataTable object into an array of DataRows. What is an elegant way of doing this?

My first question would be why? The request makes no sense.
The answer is:
DataRow[] rows = myDataTable.Select();

Actually the DataTable has a property called Rows, witch provides the methods to do this.
You can accomplish this doing:
List<System.Data.DataRow> r = d.Rows.AsQueryable().OfType<System.Data.DataRow>().ToList();

DataTable.Select() gives you an array of DataRows. You can use this as an array
Dim dt As New DataTable
Dim dr() As DataRow = dt.Select()
In case you want an ArrayList, you can
public ArrayList ConvertDT(ref DataTable dt)
{
ArrayList converted = new ArrayList(dt.Rows.Count);
foreach (DataRow row in dt.Rows)
{
converted.Add(row);
}
return converted;
}
I have not used the dt.rows.CopyTo function. maybe that works also.

If you would like to see the contents as a string, use this code:
string.Join(",", dataTable.AsEnumerable().SelectMany(row => row.ItemArray))

Related

C# Datatable to Dictionary

C#:
I have a datatable with a variable number of columns - returned by calling a stored procedure.
and I would like to convert it to Dictionary key-value pairs (string).
How do I achieve this without having to iterate through each column in each row? I won't know how many columns are there in the datatable at any time.
Thanks
G
You said your result should contain values for the first (and only) row of the dataTable
This one liner can do the trick
var res = dt.Columns.Cast<DataColumn>().ToDictionary(col => col.ColumnName, col=>dt.Rows[0][col]);
ToDictionary will internally enumerate the columns
But I really prefer this explicit enumeration:
var row = dt.Rows[0];
var res2 = new Dictionary<string, object>();
foreach (DataColumn col in dt.Columns)
res2.Add(col.ColumnName, row[col]);
The second is much more readable IMHO.
You can use a method like this calling the extension method ToDictionary() :
internal Dictionary<string,object> GetDict(DataTable dt)
{
return dt.AsEnumerable()
.ToDictionary(row => row.Field<string>(0),
row => row.Field<object>(1));
}

Adding DataRow items from collection of values

I am trying to create a DataRow which gets some values from hard-coded strings or string variables, and the rest of the values from a collection's values, System.Collections.Generic.Dictionary<string, double>.ValueCollection to be specific. In my attempt below, I'm casting to an array but that doesn't work.
DataTable source = new DataTable();
foreach (string sample in GridSource.SampleName)
{
SampleDictionaries sd = GridSource.Data.Where(x => GridSource.Data.IndexOf(x) == GridSource.SampleName.IndexOf(sample)).First();
source.Rows.Add(sample, "Average", sd.Avg.Values.ToArray());
source.Rows.Add("", "Std. Deviation", sd.StdDev.Values.ToArray());
}
The code above produces this:
I understand what is happening here. My question is this: is there an easy way to tell the DataRow "Fill the remaining column values with this collection," or am I going to have to come up with some loop to do it?
what you can do is create the row from the datatable.NewRow() method. Then you can have the items array of the row equal an array of data:
DataTable source = new DataTable();
foreach (string sample in GridSource.SampleName)
{
DataRow temp = source.NewRow();
SampleDictionaries sd = GridSource.Data.Where(x => GridSource.Data.IndexOf(x) == GridSource.SampleName.IndexOf(sample)).First();
temp.ItemArray = new object[]{sample, "Average"}.Concat(sd.Avg.Values.ToArray());
source.Rows.Add(temp);
temp = source.NewRow();
temp.ItemArray = new object[]{"", "Std. Deviation".Concat(sd.StdDev.Values.ToArray());
}
Found an answer, with help from KMoussa!
source.Rows.Add(new object[] { "", "Std. Deviation"}.Concat(sd.StdDev.Values.Cast<object>().ToArray()).ToArray());
Very similar to what he recommended, but it was missing a second cast to array at the end.

How can I populate a generic list of string with the results from a single-column DataTable?

I see a lot of complex examples for converting a DataTable with multiple-member rows here but in my case, the query simply returns one column from a table, that is to say 0..N strings/varchars, such as:
bbfinaleofseem#wallacestevens.org
eyenoy#dunbar.com
I thought something like this should work:
DataTable UnitReportPairEmailValsDT = new DataTable();
string qry = string.Format(SQL.UnitReportPairEmailQuery, unit, rptId);
UnitReportPairEmailValsDT = SQL.ExecuteSQLReturnDataTable(
qry,
CommandType.Text,
null
);
List<String> emailAddresses = new List<string>();
foreach (string emailaddr in UnitReportPairEmailValsDT)
{
emailAddresses.Add(emailaddr);
}
...but it won't compile ("foreach statement cannot operate on variables of type 'System.Data.DataTable' because 'System.Data.DataTable' does not contain a public definition for 'GetEnumerator'")
I tried appending ".AsEnumerable" to "in UnitReportPairEmailValsDT" too, but that also provoked the wrath of the compiler.
Error says you cannot loop through DataTable object itself, probably what you need is looping through DataRows.
Use this.
foreach(DataRow row in UnitReportPairEmailValsDT.Rows)
{
emailAddresses.Add(row["emailaddr"].ToString()); // assuming you have emailaddr column.
}
Other option, use Linq
emailAddresses = UnitReportPairEmailValsDT
.AsEnumerable()
.Select(row=> row.Field<string>("emailaddr"))
.ToList();
try something like this:
List<String> emailAddresses = new List<string>();
foreach (DataRow row in UnitReportPairEmailValsDT.Rows)
{
emailAddresses.Add(row.Item(0));
}
Suppose dt is your data table then using Linq:
dt.Rows.Select(x=> x[0]+"").ToList() will give you List. Beware of using Select(x=>xToString()) as it is prone to error if column value is null. x[0]+"" makes sure that in case of null empty string is returned.

how can i convert arraylist to string[]? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Convert ArrayList into string array(string[]) in c#
How can I convert array list to string[]?below is code I am trying. I am getting an error:
At least one element in the source array could not be cast down to the destination array type.
ArrayList myArrayList = new ArrayList();
foreach (DataRow dtRow in DtSet.Tables[0].Rows)
{
myArrayList.Add(dtRow);
}
string[] myStringArray = (string[])myArrayList.ToArray(typeof(string));
Are you still using .NET 1.1. or why don't you use typed List<T> instead of an ArrayList?
First, you cannot cast a DataRow to String. You can cast every field of a DataRow to a string.
If you can use Linq you can use following code to get a String[] of all row fields where each field is separated by comma:
String[] rowFields = DtSet.Tables[0]
.AsEnumerable()
.Select(r => string.Join(",", r.ItemArray));
.ToArray();
You cannot take a DataRow (type) and add it to an ArrayList expecting it to be a string.
A DataRow is an object that has a myriad of information about the object as well as the objects data.
foreach(DataRow dtRow in dtSet.Tables[0].Rows)
{
myArrayList.Add(dtRow["UserName"].ToString());
}
string[] myArray = myArrayList.ToArray(typeof(string));
You are placing a number of DataRow objects into an ArrayList. DataRows are not strings. So: that can't work. At best, you can perhaps get the .ToString(), but frankly, that isn't going to be all that helpful - because every row will just say System.Data.DataRow (since it doesn't override ToString(). I think you need to re-evaluate what you are trying to do.
Example based on comment discussion:
DataTable table = ...
string[] strings = new string[table.Rows.Count];
int idx = 0;
foreach(DataRow row in table.Rows)
{
StringBuilder sb = new StringBuilder();
object[] cells = row.ItemArray;
for(int i = 0 ; i < cells.Length ; i++)
{
if (i != 0) sb.Append(',');
sb.Append('"').Append(cells[i]).Append('"');
}
strings[idx++] = sb.ToString();
}
You have an ArrayList whose elements are of type DataRow. You are trying to convert it into an array of strings. A DataRow is not a string (nor does it become one on downcasting), so you can't do that.
If the array of strings is what you ultimately want, you should probably call ToString (or whatever conversion you need) on each element while filling the ArrayList.
(Also, as Tim Schmelter said in comments, you should really be using a List<T> for some T -- probably either string or DataRow, depending on exactly how your code ends up looking -- rather than an ArrayList.)
Each item the arrayList is of type DataRow, you can't cast it to a string.
Instead, you should construct a string that represents the contents of the row, and add that string to the list, e.g.
myArrayList.Add(dtRow["CustomerName"]);
Have you tried this:
string[] array = myArrayList.ToArray(typeof(string)) as string[];
ArrayList myArrayList = new ArrayList();
myArrayList.Add("as");
myArrayList.Add("as");
myArrayList.Add("as");
myArrayList.Add("as");
myArrayList.Add("as");
myArrayList.Add("as");
string[] array = myArrayList.ToArray(typeof(string)) as string[];
foreach (var item in array)
{
Console.WriteLine(item.ToString());
}
Output:
as
as
as
as
as
as

Best practice when converting DataColumn values to an array of strings?

Best practice when converting DataColumn values to an array of strings?
[Edit]
All values for certain DataColumn for all DataTable rows to be converted to an array of string?
If I understood your goal you want to specify a particular column and return all its values as a string array.
Try these approaches out:
int columnIndex = 2; // desired column index
// for loop approach
string[] results = new string[dt.Rows.Count];
for (int index = 0; index < dt.Rows.Count; index++)
{
results[index] = dt.Rows[index][columnIndex].ToString();
}
// LINQ
var result = dt.Rows.Cast<DataRow>()
.Select(row => row[columnIndex].ToString())
.ToArray();
You could replace columnIndex with columnName instead, for example:
string columnName = "OrderId";"
EDIT: you've asked for a string array specifically but in case you're flexible about the requirements I would prefer a List<string> to avoid the need to determine the array length prior to the for loop in the first example and simply add items to it. It's also a good opportunity to use a foreach loop instead.
I would then rewrite the code as follows:
List<string> list = new List<string>();
foreach (DataRow row in dt.Rows)
{
list.Add(row[columnIndex].ToString());
}
DataRow.ItemArray Property -
http://msdn.microsoft.com/en-us/library/system.data.datarow.itemarray.aspx
Also, which version are you using? You should check out the DataTableExtensions class -
http://msdn.microsoft.com/en-us/library/system.data.datatableextensions.aspx
And the DataRowExtensions class -
http://msdn.microsoft.com/en-us/library/system.data.datarowextensions.aspx
I know this question is old, but I found it in my Google search trying to do something similar. I wanted to create a list from all the values contained in a specific row of my datatable. In my code example below, I added a SQL datasource to my project in Visual Studio using the GUI wizards and I dropped the needed table adapter into the designer.
'Create a private DataTable
Private authTable As New qmgmtDataSet.AuthoritiesDataTable
'Fill the private table using the table adapter
Me.AuthoritiesTableAdapter1.Fill(Me.authTable)
'Make the list of values
Dim authNames As List(Of String) = New List(Of String)(From value As qmgmtDataSet.AuthoritiesRow In Me.authTable.Rows Select names.authName)

Categories