将Ado.net DataReader转换为IDataRecord会产生奇怪的结果
我有一个针对数据库运行的查询,我可以看到有一个31/05/2013的记录。 当我使用ADO.NET从C#运行此查询,然后使用以下代码时,我错过了31/05/2013的记录
var timeSeriesList = new List(); using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { timeSeriesList = reader.Cast() .Select(r => new TimeSeries { MidRate = (double)r["MidRate"], RiskFactorName = (string)r["RiskFactorName"], SeriesDate = (DateTime)r["SeriesDate"] }).ToList(); } }
但是,如果我对此代码使用相同的查询:
var timeSeriesList = new List(); 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日的记录在集合中 – 为什么第一个代码块会给出这个结果?
我认为你在第一个例子中缺少记录,因为你将读者移动一个然后再将其转换。
尝试此更改,看看它是否有效:
var timeSeries = new List(); using (var reader = cmd.ExecuteReader()) { if (reader.HasRows) { timeSeries = reader.Cast() .Select(r => new TimeSeries { MidRate = (double)r["MidRate"], RiskFactorName = (string)r["RiskFactorName"], SeriesDate = (DateTime)r["SeriesDate"] }).ToList(); } }
有两种方法可以通过数据读取器进行迭代; 一个是继续打电话.Read()
; 另一种方法是将它作为IDataRecord
的IEnumerable
序列处理并foreach
它; 无论您选择哪种,您只能迭代一次数据。
- 对
.Read()
的调用从BOF移动到第一个记录(如果有的话)-
ToList()
在一个循环中调用GetEnumerator()
然后MoveNext()
,该循环立即向前移动一个位置 (所以我们将第一个记录放在地板上而不处理它); 在ToList()
的末尾,我们已经咀嚼了所有数据
-
- 所以外部
.Read()
将报告false
(EOF)
基本上:这里的问题是使用两个API来推进这个位置。 使用.Read()
,或使用foreach
API( .ToList()
)。
作为旁注,由于列名称与成员名称匹配,您还可以使用“dapper”来完成繁重的工作:
var list = conn.Query(sql, args).ToList();