Mapping to Sub-Class Using MapBuilder

Topics: Data Access Application Block, General discussion
May 15, 2010 at 12:56 AM

Hi,

In my web application I have 2 classes - Address and User like so:

    public class Address
    {
        public String StreetAddress { get; set; }
        public String City { get; set; }
        public String State { get; set; }
        public String Zip { get; set; }
    }


    public class User
    {
        public Guid UserID { get; private set; }
        public string Username { get; set; }
        public string FullName { get; set; }
        public Address ShippingAddress { get; set; }
    }

I have a method which returns the user info from a stored procedure like so:

        public User GetUserByUsername(string username)
        {
            return myDatabase.ExecuteSprocAccessor<User>
                ("stp_GetUserDetails",
                MapBuilder<User>.MapNoProperties()
                .Map(r => r.UserID).ToColumn("userID")
                .Map(r => r.Username).ToColumn("UserName")
                .Map(r => r.FullName).ToColumn("fullname")
                .Map(r => r.ShippingAddress.StreetAddress).ToColumn("addrLn1")
                .Map(r => r.ShippingAddress.City).ToColumn("city")
                .Map(r => r.ShippingAddress.State).ToColumn("state")
                .Map(r => r.ShippingAddress.Country).ToColumn("country")
                .Map(r => r.ShippingAddress.Zip).ToColumn("zipCode")
                .Build(),
                username
                ).SingleOrDefault();
        }

But this method gives the following error unless I comment out the lines that map the shipping address details:

 System.ArgumentNullException was unhandled by user code
   Message=Value cannot be null.
 Parameter name: key

How can I map to the Address sub class?


Thanks,
ywb

May 16, 2010 at 2:13 AM

Mapbuilder is (deliberately) limited in what it can map. In specific, this scenario, mapping to fields of a child object, is not supported. If you wish to implement this you'll need to provide your own implementation of IRowMapper.

Another option would be to use MapBuilder to map to a flat object, then use Linq to Objects to do a second mapping to the final object layout you want.

 

May 17, 2010 at 6:15 PM

Thanks for the reply. In that case I'll write a method to convert the DataSet to the object, like I have always done before...

 

Any reason why there's this deliberate limitation?

May 17, 2010 at 11:51 PM

The reasons are partly resources, partly guidance, and partly political. Resources because once we start adding various mapping scenarios, we could have consumed the entire project's budget and time just implementing and testing more and more of them. Guidance, in that once you start getting sophisticated mapping you should probably be using an ORM tool, not the DAAB. Political because, well, it's probably better for my career not to get into the details, but you could probably guess. :-)

So we deliberately kept it small and simple, targeting the 80% case while allowing extensions for those who'd like to do more with it.

 

Jul 23, 2010 at 12:00 PM

I think in this case, one should use the IResultSetMapper instead of rowmapper, that is specifically there for a complex graph of objects.