68

目前,当我遍历DataRow实例时,我会这样做。

foreach(DataRow row in table)
  return yield new Thingy { Name = row["hazaa"] };

迟早(即早),我会让桌子丢失列,便便会撞到风扇。经过一番广泛的谷歌搜索(大约 30 秒),我发现了以下保护语法。

foreach(DataRow row in table)
  if(row.Table.Columns.Contains("donkey"))
    return yield new Thingy { Name = row["hazaa"] };
  else
    return null;

现在 - 这是最简单的语法吗?!真的吗?我期待一种方法可以让我获得该字段,如果它存在或null否则。或者至少直接在row上使用Contains方法。

我错过了什么吗?我将以这种方式在许多领域进行映射,因此代码看起来非常难以阅读......

4

6 回答 6

124

您可以创建一个扩展方法以使其更清洁:

static class DataRowExtensions
{
    public static object GetValue(this DataRow row, string column)
    {
        return row.Table.Columns.Contains(column) ? row[column] : null;
    }
}

现在像下面这样调用它:

foreach(DataRow row in table)
    return yield new Thingy { Name = row.GetValue("hazaa") };
于 2013-08-13T11:54:56.323 回答
21

由于您的 DataTable 表始终具有相同的列(它们不会因任何行而改变),因此您只需检查一次列名。

if (table.Columns.Contains("donkey"))
{
    foreach ...
}
于 2013-08-13T11:52:32.537 回答
5

要构建 Varun K 的答案,请使用泛型类型参数:

public static T GetValue<T>(this DataRow row, string column)
{
    if (!row.Table.Columns.Contains(column))
        return default(T);

    object value = row[ColumnName];
    if (value == DBNull.Value)
        return default(T);
    return (T)value;
}
于 2019-12-12T00:11:30.697 回答
5

我真的很喜欢@Varun K 采用的方法。因此,以此为出发点,我只想投入两分钱,以防它对其他人有所帮助。我只是对其进行了改进,使其具有 通用性,而不仅仅是使用对象作为返回类型。

static class Extensions
{
  public static T Get<T>(this DataRow self, string column)
  {
    return self.Table.Columns.Contains(column)
      ? (T)self[column]
      : default(T);
    }
  }
}
于 2021-02-19T13:43:47.750 回答
3
foreach (DataColumn item in row.Table.Columns)
{
    switch (item.ColumnName)
    {
        case "ID":
            {
                p.ID = Convert.ToInt32(row[item.ColumnName].ToString());
            }
            break;
        case "firstName":
            {
                p.firstName = row[item.ColumnName].ToString();
            }
            break;
        case "lastName":
            {
                p.lastName = row[item.ColumnName].ToString();
            }
            break;

        default:
            break;
    };
}
于 2013-11-27T13:52:50.090 回答
2

有时可能存在列名,但行不包含该列的数据;例如,在使用 ReadXML 填充 DataTable 之后。

一个简单、快速和安全的解决方案是使用类型检查:

if(row["columnname"].GetType() != typeof(System.DBNull)){
    //DataRow contains "columname"
}else{
    //a safe scope to set default cell data
}
于 2020-08-08T19:23:14.960 回答