2010-10-18 2 views
2

Ниже приведен метод расширения для преобразования datareader в объект с использованием класса «DataReaderInjection» на основе инжектора OMU.Метод расширения IEnumerable и Datareader, необходимые предложения

public static IEnumerable<T> MapTo<T>(this IDataReader reader) where T : new() { 
    return reader.MapTo<T>(null); 
} 

public static IEnumerable<T> MapTo<T>(this IDataReader reader, Action<IDataReader, T> customMappingFunction) where T : new() { 
    using (reader) 
     while (!reader.IsClosed && reader.Read()) { 
      var nextItem = new T(); 
      nextItem.InjectFrom<DataReaderInjection>(reader); 
      if (customMappingFunction != null) 
       customMappingFunction(reader, nextItem); 
      yield return nextItem; 
     } 
} 

этот метод имеет ошибку, так как только вы вызываете этот метод и DataReader закрывается, следующий вызов вернет пустой IEnumerable, чтобы исправить это я изменил выше код к следующему.

public static class DataAccessExtensions 
{ 
    public static IEnumerable<T> MapTo<T>(this IDataReader reader) where T : new() { 
     return reader.MapTo<T>(null); 
    } 

    private static Dictionary<int, IEnumerable> dataReaderCache = new Dictionary<int, IEnumerable>(); 
    private static object lockObj = new object(); 

    public static IEnumerable<T> MapTo<T>(this IDataReader reader, Action<IDataReader, T> customMappingFunction) where T : new() { 
     lock (lockObj) 
     { 
      if (dataReaderCache.ContainsKey(reader.GetHashCode())) 
       return dataReaderCache[reader.GetHashCode()] as IEnumerable<T>; 
     } 
     List<T> finalList = new List<T>(); 
     using (reader) { 
      while (!reader.IsClosed && reader.Read()) { 
       var nextItem = new T(); 
       nextItem 
        .InjectFrom<DataReaderInjection>(reader); 
       if (customMappingFunction != null) 
        customMappingFunction(reader, nextItem); 
       finalList.Add(nextItem); 
      } 
     } 
     lock (lockObj) 
     { 
      dataReaderCache.Add(reader.GetHashCode(), finalList); 
     } 
     return finalList; 
    } 

}

Что вы, ребята, думаете это будет работать

+1

вызов MapTo многократно по считывателю данных указывает на запах кода! Кстати, ваша альтернативная версия также не будет работать, поскольку вы создаете MappedObject каждый раз, когда вызывается MapTo. Таким образом, второй вызов будет возвращен пустой счетчик. – VinayC

+0

yes vinay, вы правы, но он ведет себя странно, хотя возвращает последний объект. весь этот код не работает. Я попытаюсь исправить код. дайте мне знать, если вы думаете, что это правильно – Mohit

ответ

3

... этот метод имеет ошибку, так как только вы вызываете этот метод и DataReader закрывается, следующий вызов будет возвращать пустой IEnumerable

Это не ошибка, datareaders - это только итераторы только для начала, вы можете только перебирать их один раз. Если вам нужно повторять результаты более одного раза, кешируйте возвращаемый IEnumerable. Самый простой способ сделать это - обернуть его в List<T>, или вы можете кэшировать его лениво, используя Rx's MemoizeAll()

+0

Спасибо Mauricio, определит, что вы посмотрите в «Rx's MemoizeAll()», я получил то, что вы пытаетесь сказать. Но я с нетерпением жду исправления этой проблемы, написав собственный код. – Mohit

Смежные вопросы