AutoMapper define mapping level

2019-06-15 02:10发布

问题:

public class Foo
{
    public string Baz { get; set; }
    public List<Bar> Bars { get; set; }
}

When I map the class above, is there any way to define how deep I want automapper to map objects? Some pseudo code of what I'm after:

var mapped = Mapper.Map<FooDTO>(foo, opt => { levels: 0 });
// result = { Baz: "" }

var mapped = Mapper.Map<FooDTO>(foo, opt => { levels: 1 });
// result = { Baz: "", Bars: [{ Blah: "" }] }

 var mapped = Mapper.Map<FooDTO>(foo, opt => { levels: 2 });
// result = { Baz: "", Bars: [{ Blah: "", Buzz: [{ Baz: "" }] }] }

// etc...

I'm currently using automapper 3.3 due to a nuget dependency.

回答1:

You can do it by providing a value at runtime as was answered in question: How to ignore a property based on a runtime condition?.

Configuration:

Mapper.CreateMap<Foo, FooDTO>().ForMember(e => e.Bars,
    o => o.Condition(c => !c.Options.Items.ContainsKey("IgnoreBars")));

Usage:

Mapper.Map<FooDTO>(foo, opts => { opts.Items["IgnoreBars"] = true; });

Same configuration approach you can apply for all your nested objects that you call levels.

If you want to achieve same behavior for your DB Entities you can use ExplicitExpansion approach as described in this answer: Is it possible to tell automapper to ignore mapping at runtime?.

Configuration:

Mapper.CreateMap<Foo, FooDTO>()
    .ForMember(e => e.Bars, o => o.ExplicitExpansion());

Usage:

dbContext.Foos.Project().To<FooDTO>(membersToExpand: d => d.Bars);


回答2:

You can define map specific MaxDepth like:

Mapper.CreateMap<Source, Destination>().MaxDepth(1);

More info: https://github.com/AutoMapper/AutoMapper/wiki



标签: c# AutoMapper