Skip to content

Compound Map

jayoungers edited this page Oct 12, 2018 · 2 revisions

In more complex scenarios you may have fields that are tightly coupled to each other and have their own sets of requirements. For these scenarios, you can create a CompoundMap, which consists of two parts: a collection of maps, and a PostMap method. If any of the fields in the collection of maps has changed, then the CompoundMap PostMap method will run.

For example:

mapper.AddCompoundMap(cm =>
{
    cm.AddMap(vm => vm.UpdatedAsOfDate, db => db.UpdatedAsOfDate);
    cm.AddMap(vm => vm.UpdatedPost.Id, db => db.UpdatedPostId);
}, (target, ctx) =>
{
    if ((target.UpdatedAsOfDate.HasValue && !target.UpdatedPostId.HasValue) || (!target.UpdatedAsOfDate.HasValue && target.UpdatedPostId.HasValue))
    {
        ctx.AddValidationResult(nameof(PostViewModel.UpdatedPost), $"Updated Post requires both a Post and an As Of Date");
    }
});

In our scenario UpdatedAsOfDate and UpdatedPost must be used in conjunction, so if one field is set, they both must be set.

Other common scenarios may be fields that are calculated based on a group of other fields (and therefore need to be recalculated when any are changed), or for logging purposes.

The map collection of a CompoundMap can contain its own set of CompoundMaps allowing for full recursion (insert mind-blown1.gif here), and the mapper itself is a CompoundMap, allowing for its own PostMap method (insert mind-blown2.gif here):

mapper.AddMap(vm => vm.Title, db => db.Title);
mapper.AddMap(vm => vm.Content, db => db.Content);

mapper.HasPostMap((target, ctx) =>
{
    //Title or Content (or both) has changed
    target.ModifiedDt = DateTimeOffset.Now;
});
Clone this wiki locally