简体   繁体   中英

Automapper: Map property of type X from source object to destination object with equivlanet properties to type X

Not sure that I'm wording this the right way so hopefully the example is clear enough.

What I'm trying to do seems pretty basic to me so I'm assuming I'm missing something obvious.

For this example, the two ForMember mappings are trivial and get the job done. The question is for a more complex class, given any intermediate mappings are configured, how do you simply map the property of one object to the entire destination?

I searched for a while now and the closest I came to finding an answer is here but the ConvertUsing syntax doesn't work for me (I'm using Automapper 4.2.1)

Here are the example classes:

public class UserRoleDto
{
    public string Name { get; set; }
    public string Description { get; set; }
}

public class DbRole
{
    public Guid RoleId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

public class DbUserRole
{
    public Guid UserId { get; set; }
    public DbRole Role { get; set; }
}

And here's my test case with the Automapper config setup (testing in LINQPad, that's what the Dump() is for at the end of the last line)

var dbRole = new DbRole { RoleId = Guid.NewGuid(), Name = "Role Name", Description = "Role Description" };
var dbUserRole = new DbUserRole { UserId = Guid.NewGuid(), Role = dbRole };

var config = new MapperConfiguration(cfg =>
    {
        cfg.CreateMap<DbRole, UserRoleDto>();

        /* Works but verbose for a class with more than a few props */
        cfg.CreateMap<DbUserRole, UserRoleDto>()
            .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Role.Name))
            .ForMember(dest => dest.Description, opt => opt.MapFrom(src => src.Role.Description))
            ;
    });

config.AssertConfigurationIsValid();
var mapper = config.CreateMapper();
var userRoleDto = mapper.Map<UserRoleDto>(dbUserRole).Dump();

How about passing in the sub-object to be mapped? Eg

cfg.CreateMap<DbRole, UserRoleDto>();

Then, instead of mapping dbUserRole , you would map dbUserRole.Role .

var userRoleDto = mapper.Map<UserRoleDto>(dbUserRole.Role);

Here is another similar example using the following classes:

public class Person
{
    public int person_id;
    public int age;
    public string name;
}

public class Address
{
    public int address_id;
    public string line1;
    public string line2;
    public string city;
    public string state;
    public string country;
    public string zip;
}

public class PersonWithAddress
{
    public int person_id;
    public int age;
    public string name;
    public InnerAddress address;
}

public class InnerAddress
{
    public string city;
    public string state;
    public string country;
}

With the following test case:

var person = new Person { person_id = 100, age = 30, name = "Fred Flintstone" };
var address = new Address { address_id = 500, line1 = "123 Main St", line2 = "Suite 3", city = "Bedrock", state = "XY", country = "GBR", zip="90210" };

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<Person, PersonWithAddress>();
    cfg.CreateMap<Address, InnerAddress>();
});

var mapper = config.CreateMapper();
var person_with_address = mapper.Map<Person, PersonWithAddress>(person);
person_with_address.address = new InnerAddress();
mapper.Map<Address, InnerAddress>(address, person_with_address.address);

Regards,

Ross

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM