2011-11-17 75 views
2

我剛剛遇到了DbEnumerator類,它自.NET 1.x起存在,主要用於數據綁定支持。 Reflector揭示了它在內部維護一個用於查找字段名稱的Hashtable,因此在迭代大型結果集並按名稱訪問字段時可能會更高效。有沒有人使用DbEnumerator

我遍歷一個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實現(返回一個非泛型枚舉器;在內部使用Hashtable而不是通用字典),因爲這意味着不再需要按索引訪問字段性能的原因。

在每次迭代中實例化DataRecordInternal實例都會產生內部開銷,這在某些情況下可能會超過緩存字段名稱查找的好處。

回答

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