In my project we are using NHibernate and Automapper to automatically map heavy database objects to light DTO object that we send across the wire. This works just fine, unless you have to map light object received to the POCO class.

Accordingly to all normal recommendations and just good common sense. You would not expose properties of your database objects with setter. Because ORM should fetch object graph in consistent state. And when you want to set Customer for Order you would probably use SetCustomer() method for better visibility and in

    public class Order
    {
        private Customer _customer = new Customer();
        public virtual int OrderId { get; set; }
        public virtual DateTime OrderDate { get; set; }
        public virtual Customer Customer { get { return _customer;}}
    }

and in mapping you would write something similar to this:

    public class OrderMap : ClassMap
    {
        public OrderMap()
        {
            WithTable("`Order`");

            Id(x => x.OrderId);
            Map(x => x.OrderDate, "OrderDate");

            References(x => x.Customer)
                .Access.AsCamelCaseField(Prefix.Underscore)
                .WithForeignKey("CustomerId");
        }
    }

as you can see, we set value for Customer using reflection deep inside of NHibernate. Also this approach ensures us that newly created Order will have default Customer object. But when we come to mapping OrderModel, which looks like below:

    [DataContract]
    public class OrderModel
    {
        [DataMember]
        public virtual int OrderId { get; set; }
        [DataMember]
        public virtual DateTime OrderDate { get; set; }
        [DataMember]
        public virtual CustomerModel Customer { get; set; }
    }

OrderModel.Customer simply doesn’t map to Order.Customer, since AutoMapper doesn’t have access to write into that value. Sadly, but AutoMapper doesn’t have any convention like NHibernate                 .Access.AsCamelCaseField(Prefix.Underscore), which means that it will look for _customer.

And now! AutoMapper is much smarter than NHibernate. You don’t need any conventions you can simply put private set and you are good! So I did:

    public class Order
    {
        private Customer _customer = new Customer();
        public virtual int OrderId { get; set; }
        public virtual DateTime OrderDate { get; set; }
        public virtual Customer Customer
        {
         get { return _customer;}
         private set { _customer = value;}
        }
    }

Honestly I wouldn’t write this post if I had knew about this possibility before I started writing it. But since I wrote more than half of what you see I decided to finish the story. Enjoy or blame me. Anyway for myself I took following: sniff around features and components you are using, some of them have better ideas than others, your task is to absorb the best!

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someone