DAL mapping efficiency
Use LINQ expression compilation to generate mapping code at runtime. The concept is to generate a method that does obj.Property1 = dataReader["Property1"]; ... dynamically.

public class Converter&lt;T&gt; where T : new()
{
    private static ConcurrentDictionary&lt;Type, object&gt; _convertActionMap = new ConcurrentDictionary&lt;Type, object&gt;();
    private Action&lt;IDataReader, T&gt; _convertAction;

    private static Action&lt;IDataReader, T&gt; GetMapFunc()
    {
        var exps = new List&lt;Expression&gt;();
        var paramExp = Expression.Parameter(typeof(IDataReader), "dataReader");
        var targetExp = Expression.Parameter(typeof(T), "target");
        var getPropInfo = typeof(IDataRecord).GetProperty("Item", new[] { typeof(string) });
        foreach (var property in typeof(T).GetProperties())
        {
            var getPropExp = Expression.MakeIndex(paramExp, getPropInfo, new[] { Expression.Constant(property.Name, typeof(string)) });
            var castExp = Expression.TypeAs(getPropExp, property.PropertyType);
            //var bindExp = Expression.Bind(property, castExp);
            var bindExp = Expression.Assign(Expression.Property(targetExp, property), castExp);
            exps.Add(bindExp);
        }
        return Expression.Lambda&lt;Action&lt;IDataReader, T&gt;&gt;(Expression.Block(exps), new[] { paramExp, targetExp }).Compile();
    }

    public Converter()
    {
        _convertAction = (Action&lt;IDataReader, T&gt;)_convertActionMap.GetOrAdd(typeof(T), (t) =&gt; GetMapFunc());
    }

    public T CreateItemFromRow(IDataReader dataReader)
    {
        T result = new T();
        _convertAction(dataReader, result);
        return result;
    }
}


Test method with 80,000 x 100 iteration

    static void Main(string[] args)
{
    var dummyReader = new DummyDataReader();
    var properties = typeof(DummyObject).GetProperties();
    var startDate = DateTime.Now;
    var converter = new Converter&lt;DummyObject&gt;();
    for (int i = 0; i &lt; 80000 * 100; i++)
    {
        //var obj = CreateItemFromRow2&lt;DummyObject&gt;(new DummyDataReader());
        var obj = CreateItemFromRow&lt;DummyObject&gt;(dummyReader, properties);
        //var obj = converter.CreateItemFromRow(dummyReader);
        dummyReader.DummyTail = i;
    }

    //var obj = CreateItemFromRow2&lt;DummyObject&gt;(new DummyDataReader());
    Console.WriteLine("Time used : " + (DateTime.Now - startDate).ToString());
    Console.ReadLine();
}


Result:

CreateItemFromRow : 18.5 seconds
Converter&lt;T&gt; : 7.3 seconds


Map function:

    private static IList&lt;T&gt; Map&lt;T&gt;(DbDataReader dr) where T : new()
    {
            // initialize our returnable list
            List&lt;T&gt; list = new List&lt;T&gt;();
            // fire up the lamda mapping
            var converter = new Converter&lt;T&gt;();

            while (dr.Read()) {
                // read in each row, and properly map it to our T object
                var obj = converter.CreateItemFromRow(dr);
                list.Add(obj);
            }

            // reutrn it
            return list;
     }