Do you really need a reader, or just need a way to iterate over the lines inside it? I suggest an iterator block. You can iterate over the rows in the source method and yield each row in the queue to the caller.
There is a trick with this method: because you give the same object with each iteration, there are times when this can cause a problem, and therefore you should ask the delegate to copy the contents somewhere nearby. I would also like to abstract this into a general method that can be used for any request, and use the same delegate method to process the parameter data, for example:
private IEnumerable<T> GetRows<T>(string sql, Action<SqlParameterCollection> addParameters, Func<IDataRecord, T> copyRow) { using (var cn = new SqlConnection("Connection string here")) using (var cmd = new SqlCommand(sql, cn) { cmd.CommandType = CommandType.StoredProcedure; addParameters(cmd.Parameters); cn.Open(); using (var rdr = cmd.ExecuteReader()) { while (rdr.Read()) { yield return copyRow(rdr); } rdr.Close(); } } } public IEnumerable<MenuItem> GetChildMenus(string url) { return GetRows<MenuItem>("spR_GetChildMenus", p => {
Joel Coehoorn
source share