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

时间:2013-06-04 11:41:05

标签: 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();

    }
}

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

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

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

2 个答案:

答案 0 :(得分:6)

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

尝试此更改并查看其是否有效:

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

答案 1 :(得分:3)

有两种方法可以迭代数据读取器;一个是继续打电话.Read();另一种方法是将其视为IEnumerableIDataRecord的{​​{1}}序列;无论你选择哪一个,你都只能迭代一次数据。

  • foreach的调用从BOF移动到第一条记录(如果有)
    • .Read()调用ToList()然后调用GetEnumerator()循环,立即前进一个位置(所以我们删除了第一个记录在地板上没有处理它);在MoveNext()的末尾我们已经咀嚼了所有数据
  • 因此外部ToList()将报告.Read()(EOF)

基本上:这里的问题是使用两个API来推进这个位置。使用false,或使用.Read() API(foreach)。

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

.ToList()