Get specific column from DataRow without iteration through every column - c#

Im new to DataSets and I am trying to get a specific column from a DataSet. I wrote this code
using (var dataset = new U2ZFDataSetTableAdapters.stationenTableAdapter())
{
var ds = new U2ZFDataSet();
dataset.Fill(ds.stationen);
var rows = ds.stationen.Select("pdvorhanden = 1");
foreach (DataRow row in rows)
{
foreach (DataColumn column in ds.stationen.Columns)
{
if(column.ColumnName == "Bezeichnung")
listOfStations.Add(row[column].ToString());
}
}
}
The code feels slow to me. Isnt there a better way to do this? How can I get a specific Colum from DataRow without iterating through every column of the row?

Access to the column via column name.
foreach (DataRow row in rows)
{
listOfStations.Add(row["Bezeichnung"].ToString());
}
https://msdn.microsoft.com/en-us/library/146h6tk5(v=vs.110).aspx

Related

How to copy values from a datatable column into a datagridview column in windows forms in c# without iterating every single row?

I have more than 9000 rows and 18 columns in my datagridview. I have to read the columns from an external datatable. If I find a match between column names, I have to copy all values from the datatable column into the datagridview column. My problem is, I cannot iterate over these rows for 18 times for more than 9000 rows and write for every iteration the value in the datagridview cell because it is too slow. Is there any valid alternative?
I add some code below so that you can understand better my question. Here I'm iterating the columns first, then the rows. Sorry for the indentation but I'm having problems in copy paste code on StackOverflow.
dgvMappatura is my dataGridView, dtExcel is my DataTable
foreach (DataColumn col in dtExcel.Columns)
{
if (col.ColumnName.Equals(nome_colonna_origine))
{
foreach (DataRow drExcel in dtExcel.Rows)
{
// some code to add values to datagridview from the datatable column
}
}
}
See if following is faster :
DataTable dt = new DataTable();
foreach (DataRow row in dt.AsEnumerable())
{
var matches = row.ItemArray.Select((x, i) => new { name = x.ToString(), index = i }).GroupBy(x => x.name).Where(x => x.Count() > 1).ToArray();
}

Looping though columns to store in session

So I have a DataTable which uses a "SELECT * FROM People WHERE ID = ?" you can understand that this will only retrieve one row as the ID is unique
I have casted it to a list:
List<DataTable> userInfo = (List<DataTable>)HttpContext.Current.Session["userDT"];
Now I am trying to do a foreach loop that would loop through each row and store the column into a session, this is what I have so far:
However I get an error:
Cannot convert type 'System.Data.DataTable' to 'System.Data.DataRow'
Does anyone know what I am doing wrong?
userInfo is a list of tables. You have to iterate through it, and for each table you can access that table's rows:
foreach (DataTable dt in userInfo)
{
foreach (DataColumn column in dt.Columns)
{
// if you want column names here is how you would get them
string columnName = column.ColumnName;
foreach (DataRow row in dt.Rows)
{
// if you want the values in the cells, here's where you get them
object value = row[column];
}
}
}

c# datatable select last row on a speicfic condition

I have a datatable has data like this format
........ IVR........
.........IVR........
.........IVR........
.........City1......
.........City1......
.........City1......
.........City2......
.........City2......
.........City2......
I want to take the last row of each value. in order words, the rows that are bold now
The challenge is that i wan these three rows in a datatable. I tried to search on internet but i didn't know what is the name of this feature. could you help me please
You can GroupBy() and then select last row with the help of the Last() method.
var result = from b in myDataTable.AsEnumerable()
group b by b.Field<string>("Your_Column_Name") into g
select g.Last();
DataTable filtered = myDataTable.Clone();
foreach(DataRow row in result)
{
filtered.ImportRow(row);
}
Clone clones the structure of the DataTable, including all DataTable schemas and constraints.
This can be implemented in a simple loop using a Dictionary to hold found rows:
var cRows = new Dictionary<string, DataRow>(StringComparer.InvariantCultureIgnoreCase);
foreach (DataRow oRow in oTable.Rows)
{
var sKey = oRow["KeyValue"].ToString();
if (!cRows.ContainsKey(sKey))
{
cRows.Add(sKey, oRow);
}
else
{
cRows[sKey] = oRow;
}
}
This approach will store the last row for each unique value in the column that you nominate.
To move the selected rows into a new DataTable:
var oNewTable = oTable.Clone();
foreach (var oRow in cRows.Values)
{
oNewTable.Rows.Add(oRow);
}
Clone just clones the structure of the current table, not the rows.

Adding DataColumn to DataTable

I want to move the data from a dataColumn to a specific column in my dataTable. I am not sure how to specify what column within my Datatable I want to add the datacolumn.
foreach (DataColumn col in dt.Columns)
{
dt1.Columns.Add(col);
}
I receive an exception Column 'X' already belongs to another DataTable.
You need to copy the properties like ColumnName and create new DataColumns:
foreach (DataColumn col in dt.Columns)
{
dt1.Columns.Add(col.ColumnName, col.DataType);
}
There's a reason for the ArgumentException when you add a DataColumn which already belongs to another DataTable. It would be very dangerous to allow that since a DataTable holds a reference to their columns and every column holds a reference to it's DataTable. If you would add a column to another table your code would blow sooner or later.
If you also want to copy the DataRows into the new table:
foreach (DataRow row in t1.Rows)
{
var r = t2.Rows.Add();
foreach (DataColumn col in t2.Columns)
{
r[col.ColumnName] = row[col.ColumnName];
}
}
You cannot add a DataColumn from another table, because it already has an association with it's original table and a DataColumn is passed by reference to the Add method because it's an Object. You'll have to copy it. Here's one way you can do that:
public static class DataColumnExtensions
{
public static DataColumn CopyTo(this DataColumn column, DataTable table)
{
DataColumn newColumn = new DataColumn(column.ColumnName, column.DataType, column.Expression, column.ColumnMapping);
newColumn.AllowDBNull = column.AllowDBNull;
newColumn.AutoIncrement = column.AutoIncrement;
newColumn.AutoIncrementSeed = column.AutoIncrementSeed;
newColumn.AutoIncrementStep = column.AutoIncrementStep;
newColumn.Caption = column.Caption;
newColumn.DateTimeMode = column.DateTimeMode;
newColumn.DefaultValue = column.DefaultValue;
newColumn.MaxLength = column.MaxLength;
newColumn.ReadOnly = column.ReadOnly;
newColumn.Unique = column.Unique;
table.Columns.Add(newColumn);
return newColumn;
}
public static DataColumn CopyColumnTo(this DataTable sourceTable, string columnName, DataTable destinationTable)
{
if (sourceTable.Columns.Contains(columnName))
{
return sourceTable.Columns[columnName].CopyTo(destinationTable);
}
else
{
throw new ArgumentException("The specified column does not exist", "columnName");
}
}
}
public class MyClass
{
public static void Main()
{
DataTable tableA = new DataTable("TableA");
tableA.Columns.Add("Column1", typeof(int));
tableA.Columns.Add("Column2", typeof(string));
DataTable tableB = new DataTable("TableB");
foreach (DataColumn column in tableA.Columns)
{
column.CopyTo(tableB);
}
}
}
Note that there is also an extension method that can be used to Copy individual columns by name, i.e. tableA.CopyColumnTo("Column1", tableB);.
Then you can copy the data like this if the new table is an exact copy of the original:
foreach (DataRow row in tableA.Rows)
{
tableB.Rows.Add(row.ItemArray);
}
Or in a way similar to the second piece of code in Tim Schmelter's answer if it is not an exact copy. I would, however, recommend some error checking if you aren't copying all the columns into the new table:
foreach (DataRow souceRow in sourceTable.Rows)
{
DataRow destinationRow = destinationTable.Rows.Add();
foreach (DataColumn destinationColumn in destinationTable.Columns)
{
string columnName = destinationColumn.ColumnName;
if (sourceTable.Columns.Contains(columnName))
{
destinationRow[columnName] = sourceRow[columnName];
}
}
}
this is a normal behavior, if you're adding the same column to more than one DataTable ArgumentException will be thrown.
see documentation here:
http://msdn.microsoft.com/en-us/library/55b10992.aspx
you can create a new column same as the one you already added to the original table and add it to the new table.
Table data is organized by row, then by column. You can't (that I know of) add a column of data in one shot. You will need to add the column definition to the second table and add the data to it separately.
Since your original code looped through all columns, you may be better off copying the original datatable using DataTable.Copy() and deleting what you don't want.

How to append row in DataTable?

I'm trying to append more values the rows of a DataTable. The original data read from database doesn't have two additional columns I'd like to add. I've got this so far -
myTable.Columns.Add("type", typeof(int));
myTable.Columns.Add("rate", typeof(int));
foreach (DataRow rows in myTable.Rows)
{
if (rows["dst"] == "1875")
{
//How to append values to this current row?
}
}
Please advice.
Here is the answer
foreach (DataRow rows in myTable.Rows)
{
if (rows["dst"] == "1875")
{
//How to append values to this current row?
rows["type"] = 32;
rows["rate"] = 64;
}
}
Also as a best practice - change rows in your for loop to row. It should be singular as it represents a single object - not a collection.

Categories