Question

I want to read data to a list from database.

I tried the following code

public List<T> StoredProcedureForIList<T>(string spName, params IDataParameter[] commandParameters)
{
   List<T> list = new List<T>();

   T item;
   Type listItemType = typeof(T);
   item = (T)Activator.CreateInstance(listItemType);
   list.Add(item);

   using (IDatabaseConnection connection = new DatabaseConnection())
   {
       IDbCommand cmd = connection.CreateCommandForStoredProcedure(spName);
       foreach (SqlParameter par in commandParameters)
       {
          cmd.Parameters.Add(par);
       }

       try
       {
          using (IDataReader reader = cmd.ExecuteReader())
          {
             while (reader != null && reader.Read())
             {
                for (int i = 0; i < reader.FieldCount; i++)
                {
                   var prop = listItemType.GetProperty(reader.GetName(i));
                   prop.SetValue(item, reader[i], null);
                }
                list.Add(item);
             }
          }
       }
       catch(Exception ex)
       { }

       return list;
   }
} 

But the problem is that when the for loop starts the reader loses data.

The data reader ResultView value is Enumeration yielded no results.

Was it helpful?

Solution

My guess is that some error occurs during execution of your loop. This technique...

try 
{ 
    ...
} 
catch(Exception ex) 
{ } 

...ensures that this error is ignored and all you get is an incomplete result. As you have noticed, this makes debugging quite hard. So don't do that.

Thus, the solution is:

  • remove the try-catch block (i.e., replace try { ... } catch(Exception ex) {} by ...),
  • run the code again,
  • note the error that occurs,
  • if you understand the error
    • fix it
  • else
    • ask again on StackOverflow, in a new question.

And, never, never write catch (Exception ex) {} again. ;-) Do proper error handling, or don't do error handling at all.

OTHER TIPS

The reader won't be dropping rows; the reader is pretty well-tested. Swallowing exceptions won't help. If I had to guess, the problem here is that you are adding the same item over and over. In fact, you add it N+1 times (you add it once at the top even if no rows are returned).

However, can I suggest: just use something like dapper, which does everything above, except a: it gets it right, and b: it is highly optimized (it emits custom IL to avoid constant reflection, and caches that IL). It would be something akin to:

var list = connection.Query<T>(procName, namedArgs,
       commandType: CommandType.StoredProcedure).ToList();

where namedArgs would be, to pass in @id and @name, for example:

new {id=123, name="abc"}

i.e.

int id = ...
string name = ...
var list = connection.Query<T>("MyProc", new {id, name},
       commandType: CommandType.StoredProcedure).ToList();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top