views:

54

answers:

1

I'm having a problem trying to make my LINQ to SQL queries and the mapping to my domain objects DRY without incurring the cost of multiple round trips to the db. Given this example:

var query1 = from x in db.DBProducts
            select new MyProduct
            {
                Id = x.ProductId,
                Name = x.ProductName,
                Details = new MyProductDetail
                {
                    Id = x.DBProductDetail.ProductDetailId,
                    Description = x.DBProductDetail.ProductDetailDescription
                }
            }

The query will make ONE round trip to the DB. Great! However, the problem I see with this is that eventually, I'll also have a 'GetProductDetails' method which will also need to do some of the SAME "data object -> domain object" mapping, very similar to that above.

To alleviate some of the mapping, I thought it might be a cool idea to extend the partial data object classes to do the mapping for me, like so:

public partial class DBProduct
{
    MyProduct ToDomainObject()
    {
        return new MyProduct
        {
            Id = this.ProductId,
            Name = this.ProductName,
            Details = this.DBProductDetails.ToDomainObject()
        };
    }
}

public partial class DBProductDetail
{
    MyProductDetail ToDomainObject()
    {
        return new MyProductDetail
        {
            Id = this.ProductDetailId,
            Description = this.ProductDetailDescription
        };
    }
}

Nice! Now, I could simply rewrite query1 as follows:

var query1 = from x in db.DBProducts
            select x.ToDomainObject();

This makes the code more DRY and more readable. Additionally, other queries that need to do the same type of mapping can simply use the ToDomainObject() method for the mapping. It works, but with a cost. While watching via Profiler, the first query would call the db ONCE, joining tables where necessary. The second query doesn't join appropriately, thus making multiple calls to the DB. Is there a way to accomplish what I'm trying to do: refactor LINQ to SQL queries so that the mapping to domain objects is DRY (no code duplication)?

+1  A: 

Use AutoMapper. Once you've tried it, it's unlikely you will ever see code like this:

new MyProduct
{
    Id = x.ProductId,
    Name = x.ProductName,
    Details = new MyProductDetail
    {
        Id = x.DBProductDetail.ProductDetailId,
        Description = x.DBProductDetail.ProductDetailDescription
    }
}
Darin Dimitrov