有没有人使用DbEnumerator

时间:2011-11-17 22:43:35

标签: .net ado.net

我只遇到过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实例的内部开销,这可能超过在某些情况下缓存的字段名称查找的好处。

1 个答案:

答案 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;
        }
    }
}