AutoMapper: Int to String and back again

2019-07-22 13:17发布

问题:

EDIT: to include TypeConverter

To set the stage, I am stripping out code from a existing WCF service to put into a business object (BO) that will be referenced by the WCF to provide clients with information. A requirement is to make the employeeId of an Employee object to be an integer rather than the string currently used. I'm using AutoMapper to map all of the objects between the BO and WCF so that contracts do not break. However I'm struggling with how to provide the mapping back and forth for the EmployeeId to be an integer in BO and still contractually serve strings via the WCF.

BO

public class Employee 
{
    public int Id {get; set;}
    ......
}

WCF

[DataContract(Name = "Employee", Namespace="url")]
public class Employee
{
    [DataMember(Order = 1)]
    public string Id {get; set;}
    ......
}

Mapper

Mapper.CreateMap<Employee.Entity.Employee, Employee.Service.Entity.Employee>()

PaddedStringTypeConverter class:

public class PaddedStringTypeConverter : ITypeConverter<int, string>
{
    public string Convert(ResolutionContext context)
    {
        var sourceValue = System.Convert.ToInt32(context.SourceValue);
        return sourceValue.ToString("D9");
    }
}

I've seen that I could use Custom Type Converters in AutoMapper to change the BO from an integer to our fixed length of nine characters so that an integer value of 4610 would be equivalent to a string of "000004610". However, how do I get it back to an integer value.

How would you do this?

回答1:

Create two mappings for both directions:

Mapper.CreateMap<Employee.Entity.Employee, Employee.Service.Entity.Employee>()
    .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id.ToString("D9")))
    .ReverseMap()
    .ForMember(dest => dest.Id, opt => opt.MapFrom(src => int.Parse(src)));

This creates maps in both directions and the options convert the types for that member back and forth.

ReverseMap is a shortcut for CreateMap with the source/destination types switched.



回答2:

Automapper is great for automatically mapping to/from things with the same name. If you want to change the conversion, or if the name of the thing you want to map to is different you need to use the .ForMember(). Your map would be something like this:

    Mapper.CreateMap<Employee.Entity.Employee, Employee.Service.Entity.Employee>()
    .ForMember(dest => dest.EmployeeID, expression => expression.MapFrom(src => Convert.ToInt32(src.EmployeeID)))
;

Then add the reverse custom mapping as well.

You shouldn't need you PaddedStringTypeConverter class.