Casting Ado.net DataReader to IDataRecord giving strange result

后端 未结 2 1012
感情败类
感情败类 2021-01-14 07:55

I have a query that I run against the database, and I can see that there is a record for 31/05/2013. When I run this query from C# with ADO.NET, and then use the following

相关标签:
2条回答
  • 2021-01-14 08:09

    There are two ways of iterating through a data-reader; one is to keep calling .Read(); the other is to treat it as an IEnumerable sequence of IDataRecord and foreach it; no matter which you choose you can only iterate the data once.

    • the call to .Read() moves from the BOF to the first record, if one
      • the ToList() calls GetEnumerator() then MoveNext() in a loop, which immediately moves forward one position (so we've dropped the first record on the floor without processing it); at the end of the ToList() we have chewed through all the data
    • so the outer .Read() will then report false (EOF)

    Basically: the problem here is using two APIs that progress the position. Either use .Read(), or use the foreach API (.ToList()).

    As a side note, since the column names match the member names you could also use "dapper" to do the heavy lifting:

    var list = conn.Query<TimeSeries>(sql, args).ToList();
    
    0 讨论(0)
  • 2021-01-14 08:23

    I think that you are missing record in first example because you move reader by one and then cast it.

    Try this change and see if it worked:

    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();
        }
    }
    
    0 讨论(0)
提交回复
热议问题