The Add method for a DataTable contains an overload for adding data to a table using an object array.
I would like to have an array of arrays, which I can loop through and insert into the DataTable. The code below creates an array of size 4000 and puts an array of 4 "columns" into the 0th element of the outer array (ContiguousTradeMem).
However, when I debug the last line below all the data which was in testObject (and in the cache- ContiguousTradeMem[]) does not get copied over to the DataTable()???
//The "array" which we wish to insert into the DataTable
object[] testObject = new object[4];
//Inserts some test data
for (int m = 0; m < 4; m++)
{
testObject[m] = "test";
}
//A test DataTable
DataTable test = new DataTable();
test.Columns.Add("Col1");
test.Columns.Add("Col2");
test.Columns.Add("Col3");
test.Columns.Add("Col4");
//Put the test "array" into the cache
ContiguousTradeMem[0] = testObject; //The data of testObject is fine here
//Write the cache element to the DataTable
test.Rows.Add(ContiguousTradeMem[0]); //The data is not fine in test.Rows
Actually the overload of DatarowCollection.Add takes a param array which is similar to a list of paramaters. You can initialize and add the DataRow from your array in this way:
var row = test.NewRow();
row.ItemArray = (Object[])ContiguousTradeMem[0];
test.Rows.Add(row);
params C#
test.Rows.Add adds existing DataRow object to your table. First you have to create new row, then fill it with your data, and after that - add it to your data table. Here is the code in VB, it is easy, so you will be able to translate it to C# :)
Dim t As New DataTable
Dim r As DataRow
r = t.NewRow()
r.ItemArray = testObject
t.Rows.Add(r)
I think you are trying to add 4 rows(array) to 4 columned table.
It should be logically:
DataRow newRow = test.NewRow();
newRow [0] = testObject[0];
newRow [1] = testObject[1];
newRow [2] = testObject[2];
newRow [4] = testObject[3];
test.Rows.Add(newRow );
You can also pass in an object array as well, like so:
DataTable dt = new DataTable();
dt.Clear();
dt.Columns.Add("Name");
dt.Columns.Add("Marks");
object[] o = { "Ravi", 500 };
dt.Rows.Add(o);
Or even:
dt.Rows.Add(new object[] { "Ravi", 500 });
Related
I have a very big csv file like this (more than 12K rows) ;
Comment, DateTime Name, Age, Class, Place, --> these are the header columns
Good, 03/10/2022, John, 12, 3, UK,
Bad, 12/10/2022, Tom, 15, 2, US
This is a generalized example which shows column names. But it will be more than this columns some times.
I am reading it as shown below
List<string> lines = File.ReadAllLines(System.IO.Path.ChangeExtension(FileNameWithPath, ".csv")).ToList();
I need a datatable from the above mentioned csv file but i DO NOT want Comment and Place columns in the datatable.
Can anybody show me how we can achieve this ?
Column datatypes :
DateTime --> typeof(datetime)
Name --> typeof(string)
Age --> typeof(double?)
Class --> typeof(int)
You can remove the columns using DataColumnCollection.Remove() after converting from the list to a datatable.
dt.Remove("Comments")
public static DataTable CSVtoDataTable(string filePath)
{
DataTable dtData = new DataTable();
using (StreamReader sReader = new StreamReader(filePath))
{
string[] columnHeader = sReader.ReadLine().Split(',');
foreach (string header in columnHeader)
{
dtData.Columns.Add(header);
}
while (!sReader.EndOfStream)
{
string[] rows = sReader.ReadLine().Split(',');
DataRow drRow = dtData.NewRow();
for (int i = 0; i < columnHeader.Length; i++)
{
drRow[i] = rows[i];
}
dtData.Rows.Add(drRow);
}
}
dtData.Columns.Remove("Comment");
dtData.Columns.Remove("Place");
return dtData;
}
How do i populate this dataTable with array of strings? Im using this template but i can only add data hardcoded... I have an string[]values which contains my data and that should be added to the datatable. I think its quite easy but i don't see it. i've been trying to loop through it but that doens't seem to work? Think im missing a crucial step.
I've created a my datatable here :
DataTable dt = new DataTable() { TableName = "MBR" };
Adding the columns to it
string[] columns = new string [l];
for (int i = 0; i < l; i++)
{
columns[i] = tags[i];
}
for (int i = 0; i < timeStamps.Count(); i++)
{
foreach (var item in tagCollection)
{
if (timeStamps[i].Date == item.time)
{
Console.WriteLine(item.time + " " + item.name );
}
}
}
dt.Columns.AddRange(columns.Select(c => new DataColumn(c.ToString())).ToArray());
And this i used in the template my collegue is working with and we need to provide the data here
var rows = new string[][]
{
new string[] {"1", "2", "false" },
new string[] { "test", "10000", "19.9" },
};
foreach (var row in rows)
{
dt.Rows.Add(row);
}
//Convert datatable to dataset and add it to the workbook as worksheet
ds.Tables.Add(dt);
workbook.Worksheets.Add(ds);
I've got many columns like 500+. And i need to add to each column a piece of data which i get from my string[]. which can contains 10 or 500+ records it depends. I need to add each record to a row. My columns are already working in this thing. I just need a way to add multiple Arrays to the table
This works for me:
DataTable dt = new DataTable() { TableName = "MBR" };
dt.Columns.Add(new DataColumn("A", typeof(string)));
dt.Columns.Add(new DataColumn("B", typeof(string)));
dt.Columns.Add(new DataColumn("C", typeof(string)));
var rows = new string[][]
{
new string[] {"1", "2", "false" },
new string[] { "test", "10000", "19.9" },
};
foreach (var row in rows)
{
dt.Rows.Add(row);
}
That gives me:
Here's how you might fill a datatable from a file of people:
var people = new DataTable();
people.Columns.Add("Name");//string
people.Columns.Add("Age", typeof(int));
people.Columns.Add("HireDate", typeof(DateTime));
people.Columns.Add("IsManager", typeof(bool));
foreach(var line in File.ReadLines("people.csv")){
var bits = line.Split(',');
dt.Rows.Add(new object[]{
bits[0], //Name
int.Parse(bits[1]), //Age
DateTime.Parse(bits[2]), //HireDate
bool.Parse(bits[3]) //IsManager
});
}
It would, of course, be preferable to use some library like Csvhelper if you're reading from a CSV - it can read into DataTables directly and is a lot more sophisticated than this example. This is just to show the process of "make a datatable, add columns, add rows by providing values for columns"
It would be better to create a strongly typed datatable for this:
Add a new DataSet type of file to your project and goive it a good name
Open it, right click the surface, choose Add DataTable, give it a sensible name
Right click the table, choose Add Column .. add a column and set its name, data type, default value etc...
Repeat until all columns are done
Using this in your code is mostly the same as above, except you make an instance of the table. It is an inner class so you create it using the name of the dataset too:
var dt = new YourDataSetNameHere.YourDataTableNameHere_DataTable();
//the columns are already added, you don't need to add them
foreach(var line in ...){
...
dt.Add_YourDataTableNameHere_Row(
bits[0], //Name
int.Parse(bits[1]), //Age
DateTime.Parse(bits[2]), //HireDate
bool.Parse(bits[3]) //IsManager
);
}
They're a lot nicer to use than regular weakly typed datatables
I need to join two datatable's and select all values from both table because d1 columns are dynamic i have tried with below code and getting the join value but when i select it shows in 2 DataRows it should be in one row
DataTable dtRtn = new DataTable();
var result = from d1 in dtFormData.AsEnumerable()
join d2 in dtResponderDetails.AsEnumerable()
on d1.Field<string>("ResponderId") equals d2.Field<string>("EmployeeId")
select new { d1,d2};
I need both d1 and d2 joined result to be copied to dtRtn table
Edit
I have searched but there is not straight forward answer for and all answers shows how to select specific columns
Please help thanks
You will need to first dynamically add the columns from dtFormData and dtResponderDetails to dtRtn. Then you can iterate through the results of your LINQ query and create new DataRow objects for each.
Here is a quick stab at the necessary code you would need to add to what you currently have:
// Step 1: Add all columns from your two DataTables to dtRtn
// (with a prefix to avoid naming collisions)
DataTable dtRtn = new DataTable();
CopyColumns(dtFormData, dtRtn, "FormData.");
CopyColumns(dtResponderDetails, dtRtn, "ResponderDetails.");
// Step 2: Build a collection containing all of the values for this result
var numFormColumns = dtFormData.Columns.Count;
var numResponderColumns = dtResponderDetails.Columns.Count;
foreach(var row in result) {
var targetRow = new List<object>();
PopulateRows(row.d1, numFormColumns, targetRow);
PopulateRows(row.d2, numResponderColumns, targetRow);
// Pass the values in as an array, which will convert it to a new DataRow
dtRtn.Rows.Add(targetRow.ToArray());
}
//...
private void CopyColumns(DataTable sourceTable, DataTable targetTable, string rowPrefix)
{
foreach (DataColumn column in sourceTable.Columns)
{
var rowName = String.Format("{0}{1}", rowPrefix, column.ColumnName);
targetTable.Columns.Add(rowName, column.DataType);
}
}
void PopulateRows(DataRow sourceRow, int numColumns, List<object> targetRow)
{
for(var i = 0; i < numColumns; i++) {
targetRow.Add(sourceRow[i]);
}
}
My problem is that i have a foreach loop that saves every row of data into a List and then creates a TXT from the list, the problem is that my data is saved into the TXT in this form:
["ROW1","DATA1","DATA2","DATA3","ROW2","DATA4","DATA5","DATA6"]
And i want to make my txt to have the data like this:
[["ROW1","DATA1","DATA2","DATA3"],["ROW2","DATA4","DATA5","DATA6"]]
Getting each row into a separate aditional brackets brackets("[]"), how can i do this without using another List?
This is my Foreach Loop:
List<string> listaprocedure = new List<string>();
foreach (DataRow dato in myTable.Rows)
{
foreach (DataColumn datoC in myTable.Columns)
{
listaprocedure.Add(dato[datoC].ToString());
}
}
json4 = JsonConvert.SerializeObject(procedimiento2);
System.IO.File.WriteAllText(#"C:\procedure.txt", json4);
You can manually iterate through rows, writing each one as you have read it, then add , after it (except last row). Plus add [ and ] at the beginning and end.
Quite ugly, but can help if you deal with really big table.
But the best option is to populate List<List<string>> (or string[,]).
Anyway here is working example:
using (var reader = File.CreateText("C:\\procedure.txt"))
{
// Starting outer json array
reader.WriteLine("[");
for (var rowIndex = 0; rowIndex < myTable.Rows.Count; rowIndex++)
{
var row = myTable.Rows[rowIndex];
var rowValues = new List<string>(); // can be reused if needed
foreach (DataColumn column in myTable.Columns)
rowValues.Add(row[column].ToString());
var jsonRow = JsonConvert.SerializeObject(rowValues);
// Write current row
reader.Write(jsonRow);
// Add separating comma
if (rowIndex != myTable.Rows.Count - 1)
reader.WriteLine(",");
}
// End outer json array
reader.WriteLine("]");
}
Given your sample data, this works:
var query =
from dr in myTable.Rows.OfType<DataRow>()
from dc in myTable.Columns.OfType<DataColumn>()
group dr[dc].ToString() by dc.Ordinal / 4;
var json4 = JsonConvert.SerializeObject(query);
This gives me:
[["ROW1","DATA1","DATA2","DATA3"],["ROW2","DATA4","DATA5","DATA6"]]
I used this code to initialize my data:
var myTable = new DataTable();
myTable.Columns.Add("A1", typeof(string));
myTable.Columns.Add("A2", typeof(string));
myTable.Columns.Add("A3", typeof(string));
myTable.Columns.Add("A4", typeof(string));
myTable.Columns.Add("B1", typeof(string));
myTable.Columns.Add("B2", typeof(string));
myTable.Columns.Add("B3", typeof(string));
myTable.Columns.Add("B4", typeof(string));
myTable.Rows.Add("ROW1", "DATA1", "DATA2", "DATA3", "ROW2", "DATA4", "DATA5", "DATA6");
I have a webservice (SOAP), from where I get an ArrayOfHumans (Array of Objects), I can get the array but I am having a hard time, saving it to the DB, something as simple (or maybe it is not so simple and I am just ignorant!) as taking an object from the array, and then getting the value of one property and saving that in a table column. I have the following code:
public JsonResult returnAllHumans()
{
TestService.TestServiceSoapClient soapClient = new TestService.TestServiceSoapClient();
object[] humansfromWS = soapClient.GetAllHumans();
System.Data.DataTable table = new System.Data.DataTable();
table.Columns.Add("FirstName", typeof(string));
table.Columns.Add("LastName", typeof(string));
table.Columns.Add("Gender", typeof(string));
table.Columns.Add("Age", typeof(int));
for (int i = 0; i < humansfromWS.Length; i++){
table.Rows.Add(new object[] {
humansfromWS[i].Age(); (And my problem is here!)
I have no idea what am I doing wrong to get this out of my array?, can someone point me in the right direction?
humansfromWS[i] is an object, it has no Age method. You have to cast it to the right type.
Please look at the documentation on the Add method. There are two versions of Add. One takes a DataRow, the other takes an array of values for a single row.
public JsonResult returnAllHumans()
{
TestService.TestServiceSoapClient soapClient = new TestService.TestServiceSoapClient();
object[] humansfromWS = soapClient.GetAllHumans();
System.Data.DataTable table = new System.Data.DataTable();
table.Columns.Add("FirstName", typeof(string));
table.Columns.Add("LastName", typeof(string));
table.Columns.Add("Gender", typeof(string));
table.Columns.Add("Age", typeof(int));
for (int i = 0; i < humansfromWS.Length; i++){
var humanFromWS = humansfromWS[i];
table.Rows.Add(new object[] {
humansFromWS.FirstName,
humansFromWS.LastName,
humansFromWS.Gender,
humanFromWS.Age});
}
or
for (int i = 0; i < humansfromWS.Length; i++){
var humanFromWS = humansfromWS[i];
var row = table.NewRow();
row["Age"] = humanFromWS.Age;
row["FirstName"] = humanFromWS.FirstName;
row["LastName"] = humanFromWS.LastName;
row["Gender"] = humanFromWS.Gender;
table.Rows.Add(row);
}