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

Jam*_*ers 43 c# idatareader

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

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

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

有没有更简洁的方法将"可选字段"添加到其他查询或复制加载方法,因此1版本使用可选字段而另一个不使用?

我也在2.0框架中.

Jam*_*ers 60

我最终找到了使用该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;
}
Run Code Online (Sandbox Code Playgroud)

  • 你可以改进if语句:if(reader.GetName(i).Equals(columnName,StringComparison.InvariantCultureIgnoreCase)) (9认同)

Hog*_*gan 19

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

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

或者检查列是否存在:

public bool ColumnExists(IDataReader reader, string columnName)
{

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


Kur*_*ler 6

看来我更正了.我知道你的实际列名在那里,但我走错了路.这个参考文章帮助澄清了一些事情,但我仍然不确定是否有一种优雅的方式.根据上面的链接,您可以获得包含以下内容的所有列的列表:

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

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

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


Cle*_*ent 6

Enumerable.Range(0, reader.FieldCount).Any(i => reader.GetName(i) == "ColumnName")
Run Code Online (Sandbox Code Playgroud)


gor*_*hal 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);
            }
        }
Run Code Online (Sandbox Code Playgroud)