tags:

views:

307

answers:

1

I have parent and child objects that are derived from LINQ to SQL entities. I want to map these onto some domain-friendlier DTOs. My SQL entity classes look somewhat like this:

public class SqlEntityParent
{
    public int ParentId { get; set; }
    public string Name { get; set; }
    public EntitySet<SqlEntityChild> Children { get; set; }
}

public class SqlEntityChild
{
    public int ChildId { get; set; }
    public int ParentId { get; set; }
    public int Position { get; set; }
    public string CategoryName { get; set; }
    public string CategoryValue { get; set; }
}

In this model, it's a standard one-to-many relationship between SqlEntityParent and SqlEntityChild. Some representative data would be...

Parent:

 ParentId   Name
 --------   -------
 1          Parent1

Child:

ChildId  ParentId   Position   CategoryName   CategoryValue
-------  --------   --------   ------------   -------------
1        1          1          Contents       Things
2        1          1          Group          GroupOne
3        1          2          Contents       Things
4        1          2          Group          GroupTwo

Now I want to map these data into my domain objects, which look somewhat like this:

public class DomainParent
{
    public int ParentId { get; set; }
    public string Name { get; set; }
    public List<DomainChild> Children { get; set; }
}

public class DomainChild
{
    public int Position { get; set; }
    public string Contents { get; set; }
    public string Group { get; set; }
}

In this structure, a single DomainChild object is made up of data from two SqlEntityChild objects, and the grouping is determined by the Position value of the child entity. So, these sample data represent a single DomainParent object with a list of two DomainChild objects. The first child should have a Position of 1, a Contents value of "Things", and a Group value of "GroupOne". The second child should have a Position of 2, a Contents of "Things", and a Group of "GroupTwo".

I am comfortable with getting one-to-one custom mapping set up in AutoMapper using ValueResolvers, but I am not sure how best to handle this. I created the below resolver and associated mapping for the parent entities which maps the whole list of child entities in one pass, but it seems goofy because I have to do the whole mapping of child objects manually in this resolver class.

Mapper.CreateMap<SqlEntityParent, DomainParent>()
    .ForMember(dto => dto.Children, opt => opt.ResolveUsing<MyResolver>());


public class MyResolver: ValueResolver<SqlEntityParent, List<DomainChild>>
{
    private MyDataContext db;

    public MyResolver()
    {
        db = new MyDataContext();
    }

    protected override List<DomainChild> ResolveCore(SqlEntityParent source)
    {
        // In here:
        //   1. custom LINQ queries
        //   2. manual creation of DomainChild objects
        //   3. manual mapping of SqlEntityChild to DomainChild
    }
}

So, my main question is this: is this the best I can do with AutoMapper in this situation, or is there some other more effective method that I can use?

A: 

Typically in these cases we map straight from SqlEntityChild to DomainChild, as lists, arrays and such are automatically supported. You just need to set up mappings for the element types, given that there is no extra logic besides iterating over the original Children collection.

Jimmy Bogard
Thanks for the reply. I still don't really grok how to set up a mapping from multiple SqlEntityChild objects into one DomainChild. I would certainly like to be able to do what you suggest, but it seems like all the examples I've seen have this implicit one-to-one requirement for the mapping. Do I instead need to just change the definition of a SqlEntityChild so that *it* does a better job of aggregating the multiple records before configuring the mapping to DomainChild?
Chris Farmer