65.9K
CodeProject is changing. Read more.
Home

DataReader into IEnumerable with C#

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.87/5 (8 votes)

Oct 31, 2013

CPOL
viewsIcon

91437

How to convert any datareader into generic list.

Introduction

This tip shows how to convert DataReader into IEnumerable using C# through reflection.

Background

Converting DataReader into IEnumerable with C# can be useful in these scenarios:

  • Working with LINQ and therefore with IEnumberable lists. 
  • Working with ORM with Code First and getting data from Store Procedures. 

Using the code 

Step 1. To create Reflection method.

Parameters:

  1. One object to copy value property. Observe it's a reference value.
  2. Property Name/Value to set the object.
public class Reflection
{
    public void FillObjectWithProperty(ref object objectTo, string propertyName, object propertyValue)
    {
        Type tOb2 = objectTo.GetType();
        tOb2.GetProperty(propertyName).SetValue(objectTo, propertyValue);
    }
}

Step 2. To create extension method

It is the most complex, we can find many information on Google about extension methods. The function is very detailed.

public static class IENumerableExtensions
{
    public static IEnumerable<T> FromDataReader<T>(this IEnumerable<T> list, DbDataReader dr)
    {
        //Instance reflec object from Reflection class coded above
        Reflection reflec = new Reflection();
        //Declare one "instance" object of Object type and an object list
        Object instance;
        List<Object> lstObj = new List<Object>();
        
        //dataReader loop
       while (dr.Read()){
           //Create an instance of the object needed.
           //The instance is created by obtaining the object type T of the object
           //list, which is the object that calls the extension method
           //Type T is inferred and is instantiated
           instance= Activator.CreateInstance(list.GetType().GetGenericArguments()[0]);
             
           // Loop all the fields of each row of dataReader, and through the object
           // reflector (first step method) fill the object instance with the datareader values
           foreach (DataRow drow in dr.GetSchemaTable().Rows){
               reflec.FillObjectWithProperty(ref instance, 
                       drow.ItemArray[0].ToString(), dr[drow.ItemArray[0].ToString()]);
           }
             
           //Add object instance to list
           lstObj.Add(instance);
       }

       List lstResult = new List();
       foreach (Object item in lstObj){
           lstResult.Add((T)Convert.ChangeType(item, typeof(T)));
       }

       return lstResult;
   }
}

Step 3. Sample of call extension method

T: Any Generics Type.  dr: DataReader

List<T> list = new List<T>().FromDataReader(dr).ToList();