.net - 有没有人使用 DbEnumerator

我刚刚遇到 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 数据库

django - 如何更改方法 is_valid() 中的表单字段

macos - Mac 上的实时动态壁纸(桌面)

iphone - 使用场景转换动画化 UIKit 项目

sql-server - 'Insert into linked table failed, RAI