C# IEnumerable和Datareader扩展方法,需要建议

C# IEnumerable和Datareader扩展方法,需要建议,c#,C#,下面是使用基于OMU值注入器的“DataReaderInjection”类将datareader转换为对象的扩展方法 公共静态IEnumerable映射到(此IDataReader读取器),其中T:new(){ 返回reader.MapTo(null); } 公共静态IEnumerable映射到(此IDataReader读取器,Action customMappingFunction),其中T:new(){ 使用(读卡器) 而(!reader.IsClosed&&reader.Read()){

下面是使用基于OMU值注入器的“DataReaderInjection”类将datareader转换为对象的扩展方法

公共静态IEnumerable映射到(此IDataReader读取器),其中T:new(){
返回reader.MapTo(null);
}
公共静态IEnumerable映射到(此IDataReader读取器,Action customMappingFunction),其中T:new(){
使用(读卡器)
而(!reader.IsClosed&&reader.Read()){
var nextItem=new T();
nextItem.InjectFrom(阅读器);
if(customMappingFunction!=null)
customMappingFunction(阅读器,nextItem);
收益率;
}
}
这个方法有一个bug,因为一旦您调用这个方法并且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;
    }
公共静态类DataAccessExtensions
{
公共静态IEnumerable映射到(此IDataReader读取器),其中T:new(){
返回reader.MapTo(null);
}
私有静态字典dataReaderCache=新字典();
私有静态对象lockObj=新对象();
公共静态IEnumerable映射到(此IDataReader读取器,Action customMappingFunction),其中T:new(){
锁(lockObj)
{
if(dataReaderCache.ContainsKey(reader.GetHashCode()))
将dataReaderCache[reader.GetHashCode()]返回为IEnumerable;
}
List finalList=新列表();
使用(读卡器){
而(!reader.IsClosed&&reader.Read()){
var nextItem=new T();
nextItem
.来自(读者)的信息;
if(customMappingFunction!=null)
customMappingFunction(阅读器,nextItem);
finalist.Add(nextItem);
}
}
锁(lockObj)
{
dataReaderCache.Add(reader.GetHashCode(),finalList);
}
回归终结者;
}
}

你们认为这能起什么作用

。。。此方法有一个bug,因为一旦调用此方法并关闭datareader,下一次调用将返回一个空的IEnumerable


这不是一个bug,DataReader是只向前的迭代器,您只能对它们进行一次迭代。如果需要多次迭代结果,请缓存返回的IEnumerable。最简单的方法是将其包装在
列表中,或者您可以使用

在数据读取器上反复调用MapTo来惰性地缓存它!顺便说一句,在每次调用MapTo时创建MappedObject时,您的备用版本也将不起作用。所以第二次调用它将返回空枚举数。是的,vinay你是对的,但它的行为很奇怪,尽管它返回的是最后一个对象。总而言之,这个代码不起作用。我将尝试将代码修复。如果你认为这是对的,请告诉我谢谢毛里西奥,他会仔细研究“Rx的备忘录()”,我明白你想说的。但是,我希望通过编写自定义代码来解决这个问题。
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;
    }