DataRow: Select cell value by a given column name

C#.NetExcelDatarow

C# Problem Overview


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.

C# Solutions


Solution 1 - C#

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));
}

Solution 2 - C#

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();

Solution 3 - C#

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

        }

Solution 4 - C#

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];        
    }
}

Solution 5 - C#

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;
  }

Solution 6 - C#

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

Solution 7 - C#

for (int i=0;i < Table.Rows.Count;i++)
{
      Var YourValue = Table.Rows[i]["ColumnName"];
}

Solution 8 - C#

Be careful on datatype. If not match it will throw an error.

var fieldName = dataRow.Field<DataType>("fieldName");

Solution 9 - C#

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVaticanUKView Question on Stackoverflow
Solution 1 - C#HassanView Answer on Stackoverflow
Solution 2 - C#JimmyView Answer on Stackoverflow
Solution 3 - C#Gabriel GView Answer on Stackoverflow
Solution 4 - C#sllView Answer on Stackoverflow
Solution 5 - C#Abraham RoyView Answer on Stackoverflow
Solution 6 - C#KamranView Answer on Stackoverflow
Solution 7 - C#Himadripatel1986View Answer on Stackoverflow
Solution 8 - C#bulbul bdView Answer on Stackoverflow
Solution 9 - C#Eckart MatthiasView Answer on Stackoverflow