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, используя номер столбца, но мне не нравится это делать, поскольку, если упорядочение столбцов изменяется, программное обеспечение будет ломаться.
Ответы
Ответ 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;
}