【问题标题】:IEnumerable and Datareader extension method, suggestions neededIEnumerable 和 Datareader 扩展方法,需要建议
【发布时间】:2010-10-18 04:52:45
【问题描述】:

以下是使用基于 OMU 值注入器的“DataReaderInjection”类将数据读取器转换为对象的扩展方法。

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

}

你们觉得这会怎样

【问题讨论】:

  • 在数据读取器上反复调用 MapTo 表明代码有异味!顺便说一句,每次调用 MapTo 时,当您创建 MappedObject 时,您的备用版本也将不起作用。所以第二次调用它会返回空的枚举数。
  • 是的,你是对的,但它的行为很奇怪,尽管它返回了最后一个对象。总而言之,这段代码不起作用。我将尝试修复代码。如果您认为这是正确的,请告诉我

标签: c#


【解决方案1】:

...这个方法有一个bug,因为一旦你调用这个方法并且datareader被关闭,下一次调用将返回一个空的IEnumerable

这不是错误,数据读取器是只进的迭代器,你只能迭代它们一次。如果您需要多次迭代结果,请缓存您返回的 IEnumerable。最简单的方法是将其包装在 List&lt;T&gt; 中,或者您可以使用 Rx's MemoizeAll() 懒惰地缓存它

【讨论】:

  • 谢谢毛里西奥,一定会调查“Rx 的 MemoizeAll()”,我明白你想说的话。但是,我期待通过编写自定义代码来解决这个问题。
猜你喜欢
  • 2019-03-17
  • 1970-01-01
  • 2018-09-06
  • 2015-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-01
相关资源
最近更新 更多