我刚刚遇到 DbEnumerator
类,它自 .NET 1.x 以来就存在,主要用于数据绑定(bind)支持。 Reflector 表明它在内部维护一个用于查找字段名称的哈希表,因此在遍历大型结果集并按名称访问字段时可能会更高效。
在遍历 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();
}
...
}
似乎通过在我的 Enumerate
方法中使用 DbEnumerator
我可以免费获得缓存的字段名称查找表:
static IEnumerable<IDataRecord> Enumerate(this IDataReader reader)
{
DbEnumerator dbEnumerator = new DbEnumerator(reader);
while (dbEnumerator.MoveNext())
{
yield return (IDataRecord) dbEnumerator.Current;
}
}
关于 DbEnumerator
在一般情况下是否可能有益或其他方面的任何评论?乍一看,它看起来很有吸引力,尽管它是一个旧的 .NET 1.x 实现(返回一个非通用枚举器;在内部使用哈希表而不是通用字典),因为这意味着不再需要通过索引访问字段性能原因。
在某些情况下,每次迭代都存在 DataRecordInternal 实例实例化的内部开销,这可能超过缓存字段名称查找的好处。
最佳答案
我认为有一个扩展方法 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;
}
}
}
https://stackoverflow.com/questions/8175443/
相关文章:
ruby-on-rails-3 - 无法修改关联,因为源反射类通过 :has_many + rail
Ruby Gem 安装失败 - 执行 gem 时出错 - 未初始化的常量 Syck::Syck
html-agility-pack - html 敏捷包和文本中的三角括号
wpf - 从 DataTemplate 中的控件获取 GridViewColumn
drupal - 在 drupal 7 中将表单元素添加到节点以供用户输入
continuous-integration - 自动构建 Access 2007 数据库