我只遇到过DbEnumerator
类,它自.NET 1.x以来就存在,主要用于数据绑定支持。 Reflector揭示了内部维护Hashtable以查找字段名称,因此在迭代大型结果集并按名称访问字段时可能更有效。
在迭代IDataReader
时,我经常使用以下模式:
// Factory method to create entity from IDataRecord
private static MyEntity GetMyEntityFromRecord(IDataRecord record)
{
return new MyEntity(
(string) record["Field1"]
, ...
);
}
// Extension method to enumerate an IDataReader
static IEnumerable<IDataRecord> Enumerate(this IDataReader reader)
{
foreach(IDataRecord record in reader)
{
yield return record;
}
}
IList<MyEntity> GetMyEntities(...)
{
...
using(IDataReader reader = ...)
{
return reader.Enumerate().Select(x => GetMyEntityFromRecord(x)).ToList();
}
...
}
似乎通过在我的DbEnumerator
方法中使用Enumerate
,我可以免费获得缓存的字段名称查找表:
static IEnumerable<IDataRecord> Enumerate(this IDataReader reader)
{
DbEnumerator dbEnumerator = new DbEnumerator(reader);
while (dbEnumerator.MoveNext())
{
yield return (IDataRecord) dbEnumerator.Current;
}
}
关于DbEnumerator
是否可能有益或在一般情况下是否有其他任何评论?乍一看它看起来很有吸引力,尽管它是一个旧的.NET 1.x实现(返回一个非泛型的枚举器;在内部使用Hashtable而不是泛型字典),因为它意味着不再需要访问出于性能原因的索引字段。
在每次迭代中都存在实例化DataRecordInternal实例的内部开销,这可能超过在某些情况下缓存的字段名称查找的好处。
答案 0 :(得分:0)
我认为有一个扩展方法Enumerate()
在内部以DbEnumerator
静默包装读者,这是违反最小意料的原则。所以我用一个重载来实现它,允许调用者明确选择使用DbEnumerator
。下次我玩大型结果集时,我可能会尝试做一些基准测试。
public static IEnumerable<IDataRecord> Enumerate(this IDataReader reader)
{
return Enumerate(reader, false);
}
public static IEnumerable<IDataRecord> Enumerate(this IDataReader reader, bool useDbEnumerator)
{
if (useDbEnumerator)
{
DbEnumerator dbEnumerator = new DbEnumerator(reader);
while (dbEnumerator.MoveNext())
{
yield return (IDataRecord)dbEnumerator.Current;
}
}
else
{
while (reader.Read())
{
yield return reader;
}
}
}