我见过两种检查列是否存在于IDataReader中的常用方法:
public bool HasColumn(IDataReader reader, string columnName)
{
try
{
reader.getOrdinal(columnName)
return true;
}
catch
{
return false;
}
}或者:
public bool HasColumn(IDataReader reader, string columnName)
{
reader.GetSchemaTable()
.DefaultView.RowFilter = "ColumnName='" + columnName + "'";
return (reader.GetSchemaTable().DefaultView.Count > 0);
}就我个人而言,我使用了第二个,因为我讨厌因为这个原因而使用异常。
但是,在大型数据集上,我认为RowFilter可能需要对每列执行一次表扫描,这可能会非常慢。
有什么想法?
发布于 2009-07-14 01:05:37
我想我对这块古老的宝石有了一个合理的答案。
我会选择第一种方法,因为它简单得多。如果想要避免异常,可以缓存字段名并在缓存上执行TryGet。
public Dictionary<string,int> CacheFields(IDataReader reader)
{
var cache = new Dictionary<string,int>();
for (int i = 0; i < reader.FieldCount; i++)
{
cache[reader.GetName(i)] = i;
}
return cache;
}这种方法的优点是它更简单,并且给你更好的控制。另外,请注意,您可能想要查看不区分大小写或不区分假名的比较,这会使事情变得更棘手。
发布于 2009-01-09 23:22:47
这在很大程度上取决于您如何使用HasColumn。你是只调用一次还是两次,还是在循环中重复调用?该列是否可能存在,或者事先完全未知?
设置行筛选器可能会在每次执行一次表扫描。(而且,从理论上讲,GetSchemaTable()可以在每次调用时生成一个全新的表,这将更加昂贵--我不相信SqlDataReader会这样做,但是在IDataReader级别,谁知道呢?)但是如果你只调用它一两次,我无法想象这会有那么大的问题(除非你有成千上万的列或其他东西)。
(不过,我至少会将GetSchemaTable()的结果存储在方法内的本地变量中,以避免快速连续地调用它两次,如果不将其缓存到某个地方,则很有可能您的特定IDataReader会重新生成它。)
如果您事先知道在正常情况下,您请求的列将存在,则异常方法会更容易接受(因为列不在那里,实际上是一个例外情况)。即使不是这样,它的性能也可能稍好一些,但是,除非您反复调用它,否则您应该问问自己,性能是否真的那么令人担忧。
如果您反复调用它,您可能应该考虑一种不同的方法,比如:预先调用GetSchemaTable()一次,遍历表格,然后将字段名加载到字典或其他专为快速查找而设计的结构中。
发布于 2009-05-21 20:05:20
我不会担心性能的影响。即使您有一个包含1000列的表(这将是一个巨大的表),您仍然只进行了1000行的“表扫描”。这很可能是微不足道的。
过早的优化只会导致不必要的复杂实现。实现您认为最好的版本,然后测量性能影响。如果与您的性能要求相比无法接受,请考虑替代方案。
https://stackoverflow.com/questions/429758
复制相似问题