将Ado.net DataReader转换为IDataRecord会产生奇怪的结果

chr*_*dev 3 c# linq ado.net

我有一个针对数据库运行的查询,我可以看到有一个31/05/2013的记录.当我使用ADO.NET从C#运行此查询,然后使用以下代码时,我错过了31/05/2013的记录

var timeSeriesList = new List<TimeSeries>();  
using (var reader = cmd.ExecuteReader())
{
    while (reader.Read())
    {
        timeSeriesList = reader.Cast<IDataRecord>()
            .Select(r => new TimeSeries
                 {
                     MidRate = (double)r["MidRate"],
                     RiskFactorName = (string)r["RiskFactorName"],
                     SeriesDate = (DateTime)r["SeriesDate"]
                 }).ToList();

    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我对此代码使用相同的查询:

var timeSeriesList = new List<TimeSeries>();                        
using (var reader = cmd.ExecuteReader())
{
    while (reader.Read())
    {
        var timeSeries = new TimeSeries
                 {
                     MidRate = (double)reader["MidRate"],
                     RiskFactorName = (string)reader["RiskFactorName"],
                     SeriesDate = (DateTime)reader["SeriesDate"]
                 };

        timeSeriesList.Add(timeSeries);
    }
}
Run Code Online (Sandbox Code Playgroud)

...然后2013年5月31日的记录在集合中 - 为什么第一个代码块会给出这个结果?

gza*_*axx 7

我认为您在第一个示例中缺少记录,因为您将读者移动一个然后再将其转换.

尝试此更改,看看它是否有效:

var timeSeries = new List<TimeSeries>();  
using (var reader = cmd.ExecuteReader())
{
    if (reader.HasRows)
    {
        timeSeries = reader.Cast<IDataRecord>()
            .Select(r => new TimeSeries
                 {
                     MidRate = (double)r["MidRate"],
                     RiskFactorName = (string)r["RiskFactorName"],
                     SeriesDate = (DateTime)r["SeriesDate"]
                 }).ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ell 5

有两种方法可以迭代数据读取器;一是不断地打电话.Read();另一种是将其视为and itIEnumerable的序列;无论您选择哪一个,都只能迭代数据一次。IDataRecordforeach

  • 调用.Read()从 BOF 移动到第一条记录(如果有)
    • 然后ToList()循环调用,立即向前移动一个位置(因此我们将第一条记录放在地板上而不对其进行处理);最后我们仔细研究了所有数据GetEnumerator()MoveNext()ToList()
  • 所以外部.Read()会报告false(EOF)

基本上:这里的问题是使用两个 API 来提升位置。要么使用.Read(),要么使用foreachAPI ( .ToList())。

作为旁注,由于列名称与成员名称匹配,您还可以使用“dapper”来完成繁重的工作:

var list = conn.Query<TimeSeries>(sql, args).ToList();
Run Code Online (Sandbox Code Playgroud)