iterate through particular column in a datatable - c#

I am Working in asp.net and c#.
I have a datatable in my application with one column.I want to iterate through that column values and check those values with someother value.please tell me how to do that.I tried it with foreach but its not working.
Code:
foreach (DataRow dr in dt.Rows)
{
int code = Convert.ToInt32(dt.Rows[0]["Code"]);
if (code == pcode)
{
//do something
}
else
{ }
}
Note:
dt is my datatable with column code.I want to compare all values in column code with pcode.

int code = Convert.ToInt32(dr["Code"]);
Although you might want to check for NULL also :)

Inside your loop, access dr, instead of dt.Rows[0].

You are always accessing the first row:
dt.Rows[0]["Code"] // use dr instead of dt.Rows[0]
dt is my datatable with column code.I want to compare all values in
column code with pcode.
So am i right when i assume that you want to compare all values with one variable, if all fields equal this value, a bool variable should be true, otherwise false?
You can use Linq:
var allEqual = dt.AsEnumerable()
.All(r => r.Field<int>("Code") == pcode);
Enumerable.All determines whether all elements of a sequence satisfy a condition.

foreach (DataRow dr in dt.Rows)
{
object o = dr["Code"];
if (o != DBNull.Value) // Check for null
{
int code = Convert.ToInt32(o);
if (code == pcode)
{
//do something
}
else
{ }
}
}

Related

Use Rows.Find to Search DataTable for String Value

I have a bit of code that I'm stuck on. I am trying to search the ReasonCodeTable for some values in the DataRow from R64CodeTable so that I can update it.
Find(_rcdr["Reason Code"]) Works fine, but Find("R64") gives me an error of Input string was not in correct format
I tried Find($"R64") and Find(#"R64"), and I even tried string testme = "R64" with Find(testme). None of it works, I continue to get the same error. "R64" is the actual string/test value I want to look for in the Column values.
foreach (DataRow _rcdr in ReasonCodeTable.Rows)
{
foreach (DataRow _dr in R64CodeTable.Rows)
{
if ( (R64CodeTable.Rows.Find(_rcdr["Reason Code"]) != null) && (R64CodeTable.Rows.Find("R64") != null) )
{
_rcdr["Desciption"] = _dr["description"];
_rcdr["Who Edited"] = _dr["editwho"];
_rcdr["Last Edit (UTC)"] = _dr["editdate"];
}
}
}

Targeting a specific column in a DataRow

I'm trying to perform the C# equivalent of Select * where [columnname] = [value]. I began with a foreach loop to iterate through the table row by row, however I had forgotten that one cannot access a column via row.column["<colname>"].
How do I achieve this objective? Most of the examples I have seen target one specific row with the intention of casting it's value to a string, however my task is to move all entries with a value of DateTime == < DateTime.Today to an archived table.
Can I continue with the following code? Or am I approaching this in the wrong manner?
void archiveDates()
{
foreach (DataRow row in workingupdates.storageTable.Rows)
{
//target DateTime column here
}
}
You can use the Field extension method that is strongly typed and also supports nullable types. You have an overload for the index, name or the DataColumn(among others):
foreach (DataRow row in workingupdates.storageTable.Rows)
{
DateTime dt = row.Field<DateTime>("columnname");
}
If you instead want to find all rows where the date column has a specific value you can use Linq-To-DataTable:
var matchingDataRows = workingupdates.storageTable.AsEnumerable()
.Where(row => row.Field<DateTime>("columnname") == dateTimeVariable);
Now you can simply enumerate this query:
foreach (DataRow row in matchingDataRows)
{
// ...
}
Or create a collection like
a DataRow[] with matchingDataRows.ToArray() or
a List<DataRow> with matchingDataRows.ToList()
a new DataTable with matchingDataRows.CopyToDataTable()
Note that you have to add System.Linq; to the top of the file.

comparing datarow value with a string in if

I have an application which stores a user selected value to the value in my dataset filled datatable. I need to set another column in the table based on this comparison. But the comparison is not working. It always returns false, not entering in the if condition.
foreach (DataRow dr in dsQuestions.Tables[0].Rows)
{
if (dr["Data"] == indicater[0])
{
dr["IsSelected"] = true;
}
}
indiactor[0] is a string array and dr["data"] is also of type string but it shows a warning that it needs to a string type.
The DataRow indexer returns the field at that index as object not as string.
I would recommend to use the strongly typed Field-extension method which also supports nullables:
if (dr.Field<String>("Data") == indicater[0]){}
... and the SetField method that also support nullable types:
dr.SetField("IsSelected", true);
Update if indicater[0] is really a string[] (not a single string), how do you want to compare a string with a string[]? If you for example want to check if the array contains this data:
if (indicater[0].Contains(dr.Field<String>("Data"))){}
That would also explain why it never enters the if: because == only compares strings by equality, other types which don't have overridden the ==-operator will compare only the reference. A string is never the same reference as a string[]. But you don't get a compile time error because you can compare an object with everything else.
First of all string can't compare using == you should use equals method:
foreach (DataRow dr in dsQuestions.Tables[0].Rows)
{
if (dr["Data"].tostring().Equals(indicater[0]))
{
dr["IsSelected"] = true;
}
May be useful for you
DataRow[] result = table.Select("Id = 1");
foreach (DataRow row in result)
{
if (row[0].Equals(indicater[0]))
{
//IsSelected
row[1]=true;
Console.WriteLine("{0}", row[0]);
}
}
Try this:
foreach (DataRow dr in dsQuestions.Tables[0].Rows)
{
if (dr["Data"].ToString() == indicater[0].ToString())
{
Convert.ToBoolean(dr["IsSelected"].ToString()) = true;
}
}

Find value from the dataview using column name

I am trying to find value from dataview using column name. My dataset shows value but my if condition returns false. I am working in asp.net using c#.
I have tried with different code. I am trying to get value like this
dv[0].DataView.Table.Columns[0].ToString().Contains("52")
//RETURN FALSE
OR
dv[0].Equals("52")
// //RETURN FALSE
OR
dv[0].Find("52")
// //RETURN FALSE
Following is my dataset
If "GBA_Nbr_GBAccount" column is a string type, it may contains spaces.
You should trim text before comparing. Try this
dv[0]["GBA_Nbr_GBAccount"].ToString().Trim().Equals("52");
You could use Linq to query the datatable or the dataview. For example, assuming your column is of type string:
var condition = yourDataTable.AsEnumerable()
.Any(r => r.Field<string>("GBA_Nbr_GBAccount") == "52");
var condition = yourDataView.Cast<DataRowView>()
.Any(rv => rv.Row.Field<string>("GBA_Nbr_GBAccount") == "52");
If the column was an integer, just change the Field<string> to Field<int> and compare against an integer, not a string
var condition = yourDataTable.AsEnumerable()
.Any(r => r.Field<int>("GBA_Nbr_GBAccount") == 52);
var condition = yourDataView.Cast<DataRowView>()
.Any(rv => rv.Row.Field<int>("GBA_Nbr_GBAccount") == 52);
Example application using string column:
static void Main(string[] args)
{
DataSet dataset = new DataSet();
dataset.Tables.Add(new DataTable("table1"));
dataset.Tables[0].Columns.Add(new DataColumn("Value", typeof(string)));
dataset.Tables[0].Rows.Add("10");
dataset.Tables[0].Rows.Add("52");
DataTable table = dataset.Tables[0];
DataView view = table.DefaultView;
var condition1 = table.AsEnumerable().Any(r => r.Field<string>("Value") == "52");
var condition2 = view.Cast<DataRowView>().Any(rv => rv.Row.Field<string>("Value") == "52");
Console.WriteLine(String.Format("Result querying datatable: '{0}'. Result using dataview:'{1}'", condition1, condition2));
Console.ReadLine();
}
If you are really using a string for the column, check for white spaces and apply a trim if needed.
One way to check for the existence of a specific column in a dataview would be like the following:
if (dv.Table.Columns["Name"] != null)
{
//Name column exists. Add Logic here
}
Use the DataViewManager object instead
it has a DataSet property associated with it and the dataset has all the normal dataset features. So, you can traverse the dataset.tables[index] object...
Hope it helps
Example: dv.DataViewManager.DataSet.Tables[0].Rows[0][1]
Thanks,
Sam
int rowIndex = dv.Find("52");
if (rowIndex == -1) {
Console.WriteLine("No match found.");
}
else {
Console.WriteLine("{0}, {1}",
dv(rowIndex)("GBA_Nbr_GBAccount").ToString(),
dv(rowIndex)("GBA_Nam_GBAccount").ToString());
}
I think that may be the solution to your problem, or at the very least point you in the right direction.

DataRow: Select cell value by a given column name

I have a problem with a DataRow that I'm really struggling with.
The datarow is read in from an Excel spreadsheet using an OleDbConnection.
If I try to select data from the DataRow using the column name, it returns DBNull even though there is data there.
But it's not quite that simple.
datarow.Table.Columns[5].ColumnName returns "my column".
datarow["my column"] returns DBNull.
datarow[5] returns 500.
datarow[datarow.Table.Columns[5].ColumnName] returns DBNull. (just to make sure its not a typo!)
I could just select things from the datarow using the column number, but I dislike doing that since if the column ordering changes, the software will break.
Which version of .NET are you using? Since .NET 3.5, there's an assembly System.Data.DataSetExtensions, which contains various useful extensions for dataTables, dataRows and the like.
You can try using
row.Field<type>("fieldName");
if that doesn't work, you can do this:
DataTable table = new DataTable();
var myColumn = table.Columns.Cast<DataColumn>().SingleOrDefault(col => col.ColumnName == "myColumnName");
if (myColumn != null)
{
// just some roww
var tableRow = table.AsEnumerable().First();
var myData = tableRow.Field<string>(myColumn);
// or if above does not work
myData = tableRow.Field<string>(table.Columns.IndexOf(myColumn));
}
This must be a new feature or something, otherwise I'm not sure why it hasn't been mentioned.
You can access the value in a column in a DataRow object using row["ColumnName"]:
DataRow row = table.Rows[0];
string rowValue = row["ColumnName"].ToString();
I find it easier to access it by doing the following:
for (int i = 0; i < Table.Rows.Count-1; i++) //Looping through rows
{
var myValue = Table.Rows[i]["MyFieldName"]; //Getting my field value
}
Hint
DataTable table = new DataTable();
table.Columns.Add("Column#1", typeof(int));
table.Columns.Add("Column#2", typeof(string));
table.Rows.Add(5, "Cell1-1");
table.Rows.Add(130, "Cell2-2");
EDIT: Added more
string cellValue = table.Rows[0].GetCellValueByName<string>("Column#2");
public static class DataRowExtensions
{
public static T GetCellValueByName<T>(this DataRow row, string columnName)
{
int index = row.Table.Columns.IndexOf(columnName);
return (index < 0 || index > row.ItemArray.Count())
? default(T)
: (T) row[index];
}
}
On top of what Jimmy said, you can also make the select generic by using Convert.ChangeType along with the necessary null checks:
public T GetColumnValue<T>(DataRow row, string columnName)
{
T value = default(T);
if (row.Table.Columns.Contains(columnName) && row[columnName] != null && !String.IsNullOrWhiteSpace(row[columnName].ToString()))
{
value = (T)Convert.ChangeType(row[columnName].ToString(), typeof(T));
}
return value;
}
You can get the column value in VB.net
Dim row As DataRow = fooTable.Rows(0)
Dim temp = Convert.ToString(row("ColumnName"))
And in C# you can use Jimmy's Answer, just be careful while converting it to ToString(). It can throw null exception if the data is null
instead Use Convert.ToString(your_expression) to avoid null exception reference
for (int i=0;i < Table.Rows.Count;i++)
{
Var YourValue = Table.Rows[i]["ColumnName"];
}
Be careful on datatype. If not match it will throw an error.
var fieldName = dataRow.Field<DataType>("fieldName");
Simple solution:
Assume sqlDt contains the DataTable, then this will give you the content of the
column named "aaa" in row is:
Dim fldContent = sqlDte.Rows(iz).ItemArray(sqlDte.Columns.Item("aaa").Ordinal)
Console.WriteLine("aaa = " & fldContent)
Edited code formatting

Categories