【问题标题】:Could not read values using IDataReader无法使用 IDataReader 读取值
【发布时间】:2011-11-24 11:34:31
【问题描述】:

我想从数据库中读取数据到列表中。

我尝试了以下代码

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

但问题是,当 for 循环启动时,读取器会丢失数据。

数据读取器 ResultView 的值为 Enumeration 没有结果。

【问题讨论】:

  • dr 来自哪里(如dr.FieldCount)?
  • 哦,对不起,它不是 dr.FieldCount 博士...问题已编辑..
  • 更明确地说“读者丢失数据”是什么意思。另外,我怀疑你可以替换 'T item;类型 listItemType = typeof(T); item = (T)Activator.CreateInstance(listItemType);' with 'T item = default(T);'
  • 你为什么要吞下异常?那是……真是个坏主意。系统可能正在非常努力告诉你哪里出了问题,而你只是把它扔掉了。

标签: c# asp.net idatareader


【解决方案1】:

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

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

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

因此,解决方案是:

  • 删除 try-catch 块(即,将 try { ... } catch(Exception ex) {} 替换为 ...),
  • 再次运行代码,
  • 注意发生的错误,
  • 如果您理解错误
    • 修复它
  • 其他
    • 在 StackOverflow 上再次提出新问题。

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

【讨论】:

    【解决方案2】:

    阅读器不会删除行;阅读器经过了很好的测试。吞咽异常不会有帮助。如果我不得不猜测,这里的问题是您一遍又一遍地添加相同的item。实际上,你添加了 N+1 次(即使没有返回任何行,你也添加了一次在顶部)。

    但是,我可以建议:只使用像 dapper 这样的东西,它可以完成上述所有操作,除了 a:它正确,b:它是高度优化的(它发出自定义 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();
    

    【讨论】:

      猜你喜欢
      • 2021-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多