A while ago, I submitted a patch to AutoMapper that added basic support for mapping data from an IDataReader/IDataRecord to an object. For those of us who don’t have the luxury to use NHibernate in their projects, this feature can save you from writing lots of repetitive and tedious code.

Its usage is pretty much the same as with regular object-to-object mapping using AutoMapper. Lets show a very simple example.

Suppose we have a view object like the one shown below:

public class SomeView
    public Int32 SomeNumber { get; private set; }
    public Guid AnId { get; private set; }
    public Double OrNothing { get; private set; }

Now when we can execute a query like this,

SELECT ColumnA AS SomeNumber,
       ColumnB AS AnId,
       ColumnC AS OrNothing
FROM SomeTable

and read the results using a data reader. Now we can use AutoMapper to map the results to instances of our view class:

var dataReader = ... // Execute a data reader
var views = Mapper.Map<IDataReader, IEnumerable<SomeView>>(_dataReader);

This results in a collection of one of or more view objects. When our query is guaranteed to always return one record, we can use the following syntax:

var dataRecord = ... // Execute data reader and read first record
var = Mapper.Map<IDataRecord, SomeView>(_dataRecord);

This approach expects that a convention is followed whereby the name of a field returned by the query matches the name of a property on the target class. Its also possible to use projection as already provided for regular object-to-object mapping.

Suppose we add a new property to our view,

public class SomeView
    public DateTime SomeDate { get; private set; }

and we modify the query so that we retrieve the corresponding date value from the database:

       ColumnD AS BirthDay
FROM SomeTable

Notice that we’ve broken the convention here and we need to use projection to ensure that the retrieved date value is mapped to the correct property.

Mapper.CreateMap<IDataRecord, SomeView>()
    .ForMember(dest => dest.SomeDateAndTime, 
               options => options.MapFrom(
               src => src.GetDateTime(src.GetOrdinal("BirthDay"))));

var dataRecord = ...    // Execute data reader and read first record
var = Mapper.Map<IDataRecord, SomeView>(_dataRecord);

Using projection we’re able to manually map from a data reader or data record. In some sense,  we’re back to square one if we have to do this for all fields. Trying to follow the convention is of course the most useful. 

I know it’s not much, but I think it can be helpful for those cases where you actually need to map from a data reader or a data record to an object.

Previous post

Welcome Two New Elegant Coders

Next post

Thanks ElegantCode for welcoming me! (Jason Jarrett, @staxmanade)


  1. October 17, 2009 at 4:19 am

    Allright, great contribution. This will save me a bunch of mapping classes. It’s small things like these that make your life so much better if you can’t use NHibernate.

  2. October 17, 2009 at 4:23 am

    Excellent Addition. I have a question, perhaps this a wrong place to ask but let me try anyway : Can it be tweaked to run under Compact Framework 3.5 ?

  3. October 17, 2009 at 9:32 am

    @PM-SilverCrux If AutoMapper can run with the Compact Framework, then yes. I guess you can ask on the user group .

  4. October 20, 2009 at 1:47 am

    […] Mapping From IDataReader/IDataRecord with AutoMapper – Jan Van Ryswyck talks about the use of a patch he submitted for AutoMapper which allows mapping to and from data readers meaning you can easily remove a lot of boilerplate mapping code in those situations too. […]

  5. October 20, 2009 at 3:41 am

    Please, any helper for Ent.Library Data Block 4.1, for reduce code lines and write elegant code ?? any suggestions ??

    Database db = DatabaseFactory.CreateDatabase(“ConnectionStrings.Oracle.D04PES01”);
    using (DbCommand cm = db.GetStoredProcCommand(“TBL_POC_TEST_TIPOS.TBL_POC_TEST_TIPOS_FBY_PK”))
    db.AddInParameter(cm, “P_ID_TEST_TIPOS”, DbType.String, id);

    // Using “using” will cause both the DataReader and connection to be
    // closed. (ExecuteReader will close the connection when the
    // DataReader is closed.)
    using (IDataReader dataReader = db.ExecuteReader(cm))
    if (dataReader.Read())
    //while (dataReader.Read())
    // factory.Add(dataReader);
    // break;
    return factory.Entity;
    thanks in advance…

  6. October 20, 2009 at 4:10 am

    Many years I use a great bltoolkit library for mapping and dataaccess:

    public class SomeView
    public Int32 SomeNumber { get; private set; }
    public Guid AnId { get; private set; }
    public Double OrNothing { get; private set; }

    // for getting list entities
    using(var db = new DbManager())
    var list = db.SetCommand(SqlQueryHere).ExecuteList();

  7. November 30, 2009 at 3:38 pm

    Could you do it with List instead of IEnumerable like so?

    var views = Mapper.Map<IDataReader, List>(_dataReader);

  8. December 1, 2009 at 9:50 am

    When I map IDataReader to IEnumerable, it fails with null reference exception in DataReaderMapper.cs at line 106 inside the following methid:

    private static void MapPropertyValues(ResolutionContext context, IMappingEngineRunner mapper, object result)
    // this is where it is failing… right at the first line
    foreach (var propertyMap in context.TypeMap.GetPropertyMaps())
    MapPropertyValue(context, mapper, result, propertyMap);

  9. August 21, 2011 at 7:20 pm

    Great!!! Very good class for using in small projects!!!