ExecuteSprocAccessor - existing object?

Topics: Data Access Application Block
Feb 9, 2012 at 3:06 PM
Edited Feb 9, 2012 at 3:09 PM

I'm trying to justify using this for existing code. All of the code we have has this basic format:

public class SomeItem {

      public SomeItem(){}

      public SomeItem(int id){
           DataAccess --> PopulateItem( this )


Now as far as I can tell, there's no way to use the Map Builder to map data to an existing object, or to extend it simply to add this feature. The best thing I've figured out how to do would be to create Factory methods for this, but this means that we can't really implement it in existing code without major refactoring. Factory method:

public static SomeItem GetById(int id) {
        return DataAccess --> ExecuteSprocAccessor ( procedure name, MapBuilder<T>.BuildAllProperties, id ) . FirstOrDefault();

Now of course I could do custom mapping for every object, or I could reimplement a generic row-mapper. Either way is reinventing the wheel.

Please let me know if there's any way to get this to work.

Feb 11, 2012 at 4:18 AM

You're right it doesn't look like the MapBuilder can handle using an existing object.  It wouldn't be much work to create your own IRowMapper<T> that uses an existing object but that still doesn't look like it helps because the MapBuilder news up a concrete ReflectionRowMapper so you would have to reimplement MapBuilder to use your new IRowMapper implementation.

Probably the least impact change would be to use the new instance created by the ExecuteSprocAccesor to populate the existing instance.  But that is not particularly elegant or efficient (to say the least).

I'm not 100% sure what are you trying to achieve.  Are you trying to introduce EntLib and mappers to your existing code?

Randy Levy
Enterprise Library support engineer

Feb 13, 2012 at 1:26 PM

Yes, I'd like to be able to use it to replace the existing data layer in different sites.

The best I was able to produce was if you were planning on creating code to map each class. Then you could use this RowMapper, and pass in a method to do the mapping.

public class GenericRowMapper<T> : IRowMapper<T> where T : class, new() {
    bool isFirst = true;
    T firstItem;
    Action<T, IDataRecord> mapper;
    public GenericRowMapper(Action<T, IDataRecord> mapper) : this(null, mapper) { }
    public GenericRowMapper(T firstItem, Action<T, IDataRecord> mapper) {
        this.firstItem = firstItem;
        this.mapper = mapper;
    public T MapRow(IDataRecord row) {
        T item = isFirst && this.firstItem != null ? this.firstItem : new T();
        mapper(item, row);
        isFirst = false;
        return item;

Feb 14, 2012 at 12:47 AM

Based on the differences in the two designs I think that the approach you've outlined is the best way.  (At least the best way I can think of.)

Randy Levy
Enterprise Library support engineer