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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1206596/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 10:54:59  来源:igfitidea点击:

Checking to see if a column exists in a data reader

c#idatareader

提问by JamesEggers

Is there a way to see if a field exists in an IDataReader-based object w/o just checking for an IndexOutOfRangeException?

有没有办法查看一个字段是否存在于基于 IDataReader 的对象中,而无需检查 IndexOutOfRangeException?

In essence, I have a method that takes an IDataReader-based object and creates a strongly-typed list of the records. In 1 instance, one data reader has a field that others do not. I don't really want to rewrite all of the queries that feed this method to include some form of this field if I don't have to. The only way I have been able to figure out how to do it so far is to throw the 1 unique field into a try/catch block as shown below.

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

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

Is there a cleaner way short of adding the "optional field" to the other queries or copying the loading method so 1 version uses the optional field and the other doesn't?

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

I'm in the 2.0 framework also.

我也在 2.0 框架中。

采纳答案by JamesEggers

I ended up finding a solution using the reader.GetName(int)method. I created the below method to encompass the logic.

我最终找到了使用该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;
}

回答by Kurt Schindler

Appears I stand corrected. I knowyour actual column names are in there, but I was going down the wrong path. This referencehelped clear things up a bit, but I'm still not sure if there's an elegant way of doing it. Adapted from the above link, you could get a list of all of your columns with the following:

看来我站得更正了。我知道你的实际列名在那里,但我走错了路。这个参考资料帮助澄清了一些事情,但我仍然不确定是否有一种优雅的方式来做到这一点。改编自上述链接,您可以获得所有列的列表,其中包含以下内容:

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

Unfortunately it appears you can only access schema.Rows by index, so I'm not sure you can get around looping through the rows first before checking by name. In that case, your original solution seems far more elegant!

不幸的是,您似乎只能按索引访问 schema.Rows,所以我不确定您是否可以在按名称检查之前先遍历行。在这种情况下,您的原始解决方案似乎要优雅得多!

Note: my original answer suggested checking for presence of a column simply by: reader.GetSchemaTable().Columns["optionalfield"].

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

回答by Seb Nilsson

Load it into a DataTable and then you can check for column:

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

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

回答by Seb Nilsson

Don't need so much complication, just this:

不需要那么多复杂,就是这个:

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

回答by gorhal

This should work, try this:

这应该有效,试试这个:

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

回答by Hogan

The following will give you a list of the column name strings given a data reader. (Remember the results are based on the last read so it may not be the same depending on what the reader read).

下面将为您提供给定数据读取器的列名称字符串列表。(请记住,结果基于上次阅读,因此根据读者阅读的内容可能会有所不同)。

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

Or to check if a column exists:

或者检查列是否存在:

public bool ColumnExists(IDataReader reader, string columnName)
{

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

回答by Clement

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