检查数据读取器中是否存在列

时间:2009-07-30 13:26:15

标签: c# idatareader

有没有办法查看基于IDataReader的对象中是否存在字段而不检查IndexOutOfRangeException?

本质上,我有一个方法,它接受一个基于IDataReader的对象,并创建一个强类型的记录列表。在一个实例中,一个数据读取器具有其他数据读取器不具有的字段。我真的不想重写所有提供此方法的查询,以便包含某些形式的此字段(如果我不需要)。到目前为止,我能够弄清楚如何做到这一点的唯一方法是将1个唯一字段抛出到try / catch块中,如下所示。

try
{
    tmp.OptionalField = reader["optionalfield"].ToString();
}
catch (IndexOutOfRangeException ex)
{
    //do nothing
}

是否有更简洁的方法将“可选字段”添加到其他查询或复制加载方法,以便1版本使用可选字段而另一个不使用?

我也在2.0框架中。

7 个答案:

答案 0 :(得分:56)

我最终使用reader.GetName(int)方法找到了解决方案。我创建了以下方法来包含逻辑。

public bool ColumnExists(IDataReader reader, string columnName)
{
    for (int i = 0; i < reader.FieldCount; i++)
    {
         if (reader.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase))
        {
            return true;
        }
    }

    return false;
}

答案 1 :(得分:19)

以下将给出一个给定数据读取器的列名字符串列表。 (请记住,结果基于上次读取,因此根据读者阅读的内容可能不一样。)

var cols = reader.GetSchemaTable()
                 .Rows
                 .OfType<DataRow>()
                 .Select(row => row["ColumnName"]);

或检查列是否存在:

public bool ColumnExists(IDataReader reader, string columnName)
{

  return reader.GetSchemaTable()
               .Rows
               .OfType<DataRow>()
               .Any(row => row["ColumnName"].ToString() == columnName);
}

答案 2 :(得分:6)

出现我的立场。我知道你的实际列名在那里,但我走错了路。 This reference帮助澄清了一些事情,但我仍然不确定是否有一种优雅的方式。根据上述链接改编,您可以获得包含以下内容的所有列的列表:

List<string> myCols = new List<string>();
DataTable schema = reader.GetSchemaTable();
foreach (DataRow row in schema.Rows)
{
    myCols.Add(row[schema.Columns["ColumnName"]]);
}

不幸的是,您似乎只能通过索引访问schema.Rows,因此我不确定您是否可以在按名称检查之前先绕过行循环。在这种情况下,您的原始解决方案似乎更优雅!

注意:我的原始答案建议只需通过以下方式检查列的存在:reader.GetSchemaTable()。Columns [“optionalfield”]。

答案 3 :(得分:6)

Enumerable.Range(0, reader.FieldCount).Any(i => reader.GetName(i) == "ColumnName")

答案 4 :(得分:5)

这应该可行,试试这个:

private static bool ColumnExists(SqlDataReader reader, string columnName)
        {
            using (var schemaTable = reader.GetSchemaTable())
            {
                if (schemaTable != null)
                    schemaTable.DefaultView.RowFilter = String.Format("ColumnName= '{0}'", columnName);

                return schemaTable != null && (schemaTable.DefaultView.Count > 0);
            }
        }

答案 5 :(得分:3)

将其加载到DataTable中,然后您可以检查列:

DataTable dataTable = new DataTable();
dataTable.Load(reader);
foreach (var item in dataTable.Rows) 
{
    bool columnExists = item.Table.Columns.Contains("ColumnName");
}

答案 6 :(得分:1)

不需要这么多复杂功能,只需这样:

bool bFieldExists = datareader.GetSchemaTable().Columns.Contains(strFieldName);