有没有办法查看基于IDataReader的对象中是否存在字段而不检查IndexOutOfRangeException?
本质上,我有一个方法,它接受一个基于IDataReader的对象,并创建一个强类型的记录列表。在一个实例中,一个数据读取器具有其他数据读取器不具有的字段。我真的不想重写所有提供此方法的查询,以便包含某些形式的此字段(如果我不需要)。到目前为止,我能够弄清楚如何做到这一点的唯一方法是将1个唯一字段抛出到try / catch块中,如下所示。
try
{
tmp.OptionalField = reader["optionalfield"].ToString();
}
catch (IndexOutOfRangeException ex)
{
//do nothing
}
是否有更简洁的方法将“可选字段”添加到其他查询或复制加载方法,以便1版本使用可选字段而另一个不使用?
我也在2.0框架中。
答案 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);