Подтвердить что ты не робот

DataRow: выбор значения ячейки по имени данного столбца

У меня проблема с DataRow, с которой я действительно борюсь.

Datarow считывается из электронной таблицы Excel с использованием OleDbConnection.

Если я попытаюсь выбрать данные из DataRow с использованием имени столбца, он возвращает DBNull, даже если там есть данные.

Но это не совсем так просто.

datarow.Table.Columns[5].ColumnName возвращает "мою колонку".
datarow["my column"] возвращает DBNull.
datarow[5] возвращает 500.
datarow[datarow.Table.Columns[5].ColumnName] возвращает DBNull. (просто чтобы убедиться, что это не опечатка!)

Я мог просто выбрать вещи из datarow, используя номер столбца, но мне не нравится это делать, поскольку, если упорядочение столбцов изменяется, программное обеспечение будет ломаться.

4b9b3361

Ответ 1

Какую версию .NET вы используете? Начиная с .NET 3.5 существует сборка System.Data.DataSetExtensions, которая содержит различные полезные расширения для dataTables, dataRows и т.п.

Вы можете попробовать использовать

row.Field<type>("fieldName");

Если это не сработает, вы можете сделать это:

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

Ответ 2

Это должна быть новая функция или что-то в этом роде, иначе я не уверен, почему она не упоминалась.

Вы можете получить доступ к значению в столбце объекта DataRow, используя row["ColumnName"]:

DataRow row = table.Rows[0];
string rowValue = row["ColumnName"].ToString();

Ответ 3

Мне будет проще получить к нему доступ, выполнив следующие действия:

        for (int i = 0; i < Table.Rows.Count-1; i++) //Looping through rows
        {
            var myValue = Table.Rows[i]["MyFieldName"]; //Getting my field value

        }

Ответ 4

Подсказка

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: добавлено больше

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

Ответ 5

В дополнение к тому, что сказал Джимми, вы также можете сделать общий выбор, используя Convert.ChangeType вместе с нулевыми проверками:

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