无法使用IDataReader读取值

无法使用IDataReader读取值

问题描述:

我想从数据库读取数据到列表。无法使用IDataReader读取值

我尝试下面的代码

public List<T> StoredProcedureForIList<T>(string spName, params IDataParameter[] commandParameters) 
{ 
    List<T> list = new List<T>(); 

    T item; 
    Type listItemType = typeof(T); 
    item = (T)Activator.CreateInstance(listItemType); 
    list.Add(item); 

    using (IDatabaseConnection connection = new DatabaseConnection()) 
    { 
     IDbCommand cmd = connection.CreateCommandForStoredProcedure(spName); 
     foreach (SqlParameter par in commandParameters) 
     { 
      cmd.Parameters.Add(par); 
     } 

     try 
     { 
      using (IDataReader reader = cmd.ExecuteReader()) 
      { 
      while (reader != null && reader.Read()) 
      { 
       for (int i = 0; i < reader.FieldCount; i++) 
       { 
        var prop = listItemType.GetProperty(reader.GetName(i)); 
        prop.SetValue(item, reader[i], null); 
       } 
       list.Add(item); 
      } 
      } 
     } 
     catch(Exception ex) 
     { } 

     return list; 
    } 
} 

但问题是,对于循环开始时,阅读器丢失数据。

数据阅读器ResultView值为枚举不会产生任何结果。

+0

哪里'dr'来自(如'dr.FieldCount')? –

+0

哦,对不起,它不dr dr.FieldCount ...问题编辑.. –

+0

更明确你的意思是'读者失去数据'。另外,我怀疑你可以替换'T项目;类型listItemType = typeof(T); item =(T)Activator。的CreateInstance(listItemType);” 'T item = default(T);' – mjwills

我的猜测是在执行循环期间发生了一些错误。这种技术...

try 
{ 
    ... 
} 
catch(Exception ex) 
{ } 

...确保这个错误被忽略,你得到的只是一个不完整的结果。正如你所注意到的,这使得调试非常困难。所以不要这样做。

因此,该解决方案是:

  • 除去try-catch块(即,通过...取代try { ... } catch(Exception ex) {}),
  • 再次运行该代码,
  • 音符时发生的错误,
  • 如果你理解错误
    • 修复它
  • else
    • 再次询问*中的一个新问题。

而且,永远,永远不要再写信catch (Exception ex) {}。 ;-) 正确错误处理,或根本不做错误处理。

读者不会丢失行;读者已经很好的测试了。吞咽异常将无济于事。如果我不得不猜测,这里的问题是你一遍又一遍地添加相同的item。事实上,你添加N + 1次(即使没有返回行,你也可以在顶部添加一次)。

但是,我可以建议:只要使用像dapper这样的东西,除了a:它正确,b:它是高度优化的(它发出自定义IL以避免持续反射,并缓存IL )。这将是一个类似于:

var list = connection.Query<T>(procName, namedArgs, 
     commandType: CommandType.StoredProcedure).ToList(); 

其中namedArgs是,在@id@name通过,例如:

new {id=123, name="abc"} 

int id = ... 
string name = ... 
var list = connection.Query<T>("MyProc", new {id, name}, 
     commandType: CommandType.StoredProcedure).ToList();