Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoMapper: string to nullable int

This is similar to a previous post of mine (AutoMapper: Int to String and back again), but it touches on another aspect this time with a nullable int.

My Business Object

public class Employee 
{
    ....
    public int? ReportsToEmployeeId {get; set;}
    ....
}

My WCF

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

Mapper

Mapper.CreateMap<Employee.Entity.Employee, Employee.Service.Entity.Employee>()
    ....
    .ForMember(dest => dest.ReportsToEmployeeId, 
        opt => opt.MapFrom(src => src.ReportsToEmployeeId.HasValue ?
            src.ReportsToEmployeeId.Value.ToString("D9") :
            string.Empty))
    ....
    .ReverseMap() 
    ....
    .ForMember(dest => dest.ReportsToEmployeeId, 
        opt => opt.MapFrom(src => string.IsNullOrWhitespace(src.ReportsToEmployeeId) ? 
          null : 
          int.Parse(src.ReportsToEmployeeId)))

I use the first opt.MapFrom to convert from integer to string and supply leading zeros if necessary. The second uses an extension to test whether the string value is null or blank and assigns it to a null or parses to an integer to fill the nullable int. However I get a build error on the null segment. The error is simply stating that it has an unknown method for ForMember or MapFrom.

Visual Studio does confirm that dest.ReportsToEmployeeId is a nullable int in the code after the ReverseMap, so it seems strange that it will not take it. If I change the code to be:

....
.ForMember(dest => dest.ReportsToEmployeeId, 
        opt => opt.MapFrom(src => string.IsNullOrWhitespace(src.ReportsToEmployeeId) ? 
          int.Parse(src.ReportsToEmployeeId) : 
          int.Parse(src.ReportsToEmployeeId)))
....

it seems to build okay. So I know it is the mapping of the null to the nullable int causing the issue.

What am I missing? Would there be a better way to approach this?

like image 337
Hitek Avatar asked Aug 14 '14 14:08

Hitek


1 Answers

I think the error you're seeing is hiding the actual problem, which is that the compiler can't determine what type you want out of the conditional:

string.IsNullOrWhiteSpace(src.ReportsToEmployeeId) ?
    null :
    int.Parse(src.ReportsToEmployeeId)

Here, the compiler does not know that you want a Nullable<int> as a result of evaluating the conditional operator. null doesn't have a type, so you need to cast it to int?:

string.IsNullOrWhiteSpace(src.ReportsToEmployeeId) ?
    (int?)null :
    int.Parse(src.ReportsToEmployeeId)

Or you could use default(int?), or new int?(), or cast the result of int.Parse to an int?.

like image 177
Andrew Whitaker Avatar answered Nov 02 '22 03:11

Andrew Whitaker