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

有没有一种方法来查看是否有一个字段存在于一个基于IDataReader的对象没有检查IndexOutOfRangeException?

实质上,我有一个方法需要一个基于IDataReader的对象,并创build一个强types的logging列表。 在一个例子中,一个数据读取器有一个其他字段没有的字段。 如果不需要的话,我不想重写所有提供此方法的查询,以包含此字段的某种forms。 到目前为止,我已经能够弄清楚如何做到的唯一方法是将1个唯一的字段放入try / catch块中,如下所示。

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

有没有更简单的方法添加“可选字段”的其他查询或复制加载方法,所以1版本使用可选字段和其他不?

我也在2.0框架。

我最终find了使用reader.GetName(int)方法的解决scheme。 我创build了下面的方法来包含逻辑。

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

下面给出一个数据读取器给出的列名string列表。 (记住结果是基于最后一次读取的,所以根据读者阅读的内容可能不一样)。

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

出现我站在纠正。 我知道你的实际列名在那里,但我走错了路。 这个参考文件有助于清除一些东西,但是我仍然不确定是否有一个很好的方法来做到这一点。 根据以上链接进行调整,您可以通过以下方式获取所有列的列表:

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

不幸的是,看起来你只能通过索引来访问schema.Rows,所以我不确定你可以在通过名字检查之前绕过循环。 在这种情况下,您的原始解决scheme似乎更加优雅!

注意:我的原始答案build议检查是否存在列简单地通过:reader.GetSchemaTable()。Columns [“optionalfield”]。

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

这应该工作,试试这个:

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

加载到一个DataTable中,然后你可以检查列:

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

不需要太多的复杂性,只是这样:

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